﻿namespace TuanHA_Combat_Routine
{
    using CommonBehaviors.Actions;
    using JetBrains.Annotations;
    using Styx;
    using Styx.Common;
    using Styx.CommonBot;
    using Styx.CommonBot.Inventory;
    using Styx.CommonBot.Routines;
    using Styx.Helpers;
    using Styx.Pathing;
    using Styx.TreeSharp;
    using Styx.WoWInternals;
    using Styx.WoWInternals.World;
    using Styx.WoWInternals.WoWObjects;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Security.Cryptography;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    using System.Windows.Media;

    public class Classname : CombatRoutine
    {
        private Composite _combatBehavior;
        private Composite _deathBehavior;
        private static DateTime _lastGetAllMyAuras = DateTime.Now;
        private Composite _preCombatBuffBehavior;
        private Composite _restBehavior;
        private static bool AoEModeOn;
        private static DateTime AutoAttackLast;
        private static readonly Dictionary<ulong, DateTime> AutoRezListCache = new Dictionary<ulong, DateTime>();
        private static readonly HashSet<int> BuffBurstHS = new HashSet<int> { 
            0x1a436, 0x3004, 0x1da7f, 0xc847, 0xbf78, 0x190a0, 0x1e82e, 0x1a1c8, 0x4c76, 0xbe5, 0x30b8, 0x7c8c, 0x19d51, 0x152aa, 0x1528d, 0xca01, 
            0xc9ea, 0x35b6, 0x1bd81, 0x1bd83, 0x1bcc2, 0x6b7, 0x1be1f
         };
        private static readonly HashSet<int> BuffEnrageHS = new HashSet<int> { 0x32f6, 0x4843, 0xd98e };
        private static readonly HashSet<int> BuffHealHS = new HashSet<int> { 
            0x306, 0x22e8, 0x83e3, 0xbd36, 0xef6f, 0x3ce, 0xca12, 0x8b, 0x12ead, 0x12eb1, 0xbd74, 0x1c1cf, 0x1e70a, 0x1c1e7, 0x1e4b1, 0x11, 
            0x81b6, 0x12b7d, 0x51bd
         };
        private static DateTime BurstLast;
        private static string CapacitorProjectionPurpose;
        private static WoWUnit CapacitorTarget;
        private static Color colorlog;
        private static bool CombatLogAttachedPvP;
        private static readonly string CombatRoutineFolder = "TuanHAShamanSpecialEdition";
        private static string CurrentSpec;
        private static bool CurrentTargetCheckDebuffCCBreakonDamage;
        private static double CurrentTargetCheckDist;
        private static bool CurrentTargetCheckFacing;
        private static bool CurrentTargetCheckInLineOfSpellSight;
        private static bool CurrentTargetCheckInvulnerable;
        private static bool CurrentTargetCheckInvulnerableMagic;
        private static bool CurrentTargetCheckInvulnerablePhysic;
        private static bool CurrentTargetCheckIsEnemy;
        private static WoWUnit CurrentTargetCheckLast;
        private static DateTime CurrentTargetCheckLastTime;
        private static TimeSpan CurrentTargetCheckTimeOut;
        private const string DB = "wc.db";
        private static readonly HashSet<int> Debuff63280DurationHS = new HashSet<int> { 
            710, 0x12bec, 0x1cb16, 0x19bcd, 0x1c428, 0x1e201, 0x1cdff, 0xae1c, 0x63, 0x25d, 0x7bad, 0x1696, 0x1cfab, 0x1fe38, 0x19c79, 0x1caaa, 
            0xd1b, 0x355, 0x1b06a, 0xa4d, 0x15a31, 0x1d120, 0x156c, 0x1ed26, 0x1c244, 0x1a85, 0x76, 0xef79, 0x6e70, 0xf119, 0xf154, 0x6e6f, 
            0xfa2c, 0x1fba, 0x1bc80, 0x1a247, 0x1c139, 0x4e62, 0x14303, 0x5e9, 0x4c2f, 0x2053c, 0x18d6, 0x250c, 0x764b, 0x154a4, 0x1966d, 0xc557, 
            0x1d079, 0x2856, 0x1a6a2
         };
        private static readonly HashSet<int> DebuffCCBreakonDamageHS = new HashSet<int> { 
            0x82e, 0x19bcd, 0x63, 0x7bad, 0xd1b, 0x6f0, 0xa4d, 0x1c244, 0x1c186, 0x1ed93, 0x1edd7, 0x76, 0xef79, 0x6e70, 0xf119, 0xf154, 
            0x6e6f, 0x4e62, 0x1a72, 0x4c2f, 0x2053c, 0x18d6, 0x1966d, 0x4bba
         };
        private static readonly HashSet<int> DebuffCCDurationHS = new HashSet<int> { 
            0x7609, 0x15ea6, 0x160e1, 710, 0x1bc89, 0x1918b, 0x12bec, 0x1cb16, 0x82e, 0x19bcd, 0x1c428, 0x1e201, 0x1edf3, 0x1dd82, 0x108b9, 0x1cdff, 
            0x83fa, 0x1bb62, 0x1ef2, 0x1d260, 0x729, 0xae1c, 0xd602, 0x63, 0x25d, 0x1d06f, 0x7bad, 0x12ec1, 0x1696, 0x1cfab, 0x1fe38, 0x7608, 
            0x19c79, 0x1caaa, 0xd1b, 0x16698, 0x6f0, 0x355, 0x1b06a, 0xc93a, 0xa4d, 0x15a31, 0x1d120, 0x156c, 0x58af, 0x1b9a0, 0x1b96c, 0x147e, 
            0x501f, 0x5f4a, 0x198, 0x1d255, 0x1ed26, 0x582a, 0x1c244, 0x145b, 0x16695, 0x1a85, 0x1c186, 0x1bd21, 0x1ed93, 0x1edd7, 0x76, 0xef79, 
            0x6e70, 0xf119, 0xf154, 0x6e6f, 0x232d, 0x19092, 0xfa2c, 0x1fba, 0x1bc80, 0x1ce49, 0x1a247, 0x340f, 0x1c139, 0x4e62, 0x14303, 0x1a72, 
            0x5e9, 0x4c2f, 0x2053c, 0x18d6, 0x250c, 0x764b, 0x20448, 0x154a4, 0x1966d, 0xc557, 0x1d079, 0xdd32, 0x1a432, 0x2856, 0x259d3, 0x5045, 
            0x19d2b, 0x4bba, 0x1a6a2
         };
        private static readonly HashSet<int> DebuffCCHS = new HashSet<int> { 
            0x7609, 0x15ea6, 0x160e1, 710, 0x1bc89, 0x1918b, 0x12bec, 0x1cb16, 0x82e, 0x19bcd, 0x1c428, 0x1e201, 0x1edf3, 0x1dd82, 0x108b9, 0x1cdff, 
            0x83fa, 0x1bb62, 0x1ef2, 0x1d260, 0x729, 0xae1c, 0xd602, 0x63, 0x25d, 0x1d06f, 0x7bad, 0x12ec1, 0x1696, 0x1cfab, 0x1fe38, 0x7608, 
            0x19c79, 0x1caaa, 0xd1b, 0x16698, 0x6f0, 0x355, 0x1b06a, 0xc93a, 0xa4d, 0x15a31, 0x1d120, 0x156c, 0x58af, 0x1b9a0, 0x1b96c, 0x147e, 
            0x501f, 0x5f4a, 0x198, 0x1d255, 0x1ed26, 0x582a, 0x1c244, 0x145b, 0x16695, 0x1a85, 0x1c186, 0x1bd21, 0x1ed93, 0x1edd7, 0x76, 0xef79, 
            0x6e70, 0xf119, 0xf154, 0x6e6f, 0x232d, 0x19092, 0xfa2c, 0x1fba, 0x1bc80, 0x1ce49, 0x1a247, 0x340f, 0x1c139, 0x4e62, 0x14303, 0x1a72, 
            0x5e9, 0x4c2f, 0x2053c, 0x18d6, 0x250c, 0x764b, 0x20448, 0x154a4, 0x1966d, 0xc557, 0x1d079, 0xdd32, 0x1a432, 0x2856, 0x259d3, 0x5045, 
            0x19d2b, 0x4bba, 0x1a6a2
         };
        private static readonly HashSet<int> DebuffCCleanseASAPHSWarrior = new HashSet<int> { 0x1696, 0x1cfab, 0x1fe38, 0xfa2c, 0x1fba, 0x1bc80 };
        private static readonly HashSet<int> DebuffCCleanseASAPPvEHS = new HashSet<int> { 
            0x1cf18, 0x1d4b1, 0x1cabc, 0x1e7bf, 0x1e083, 0x1e084, 0x21604, 0x2160f, 0x2158b, 0x21606, 0x21540, 0x21699, 0x213f9, 0x213fb, 0x213f7, 0x213f5, 
            0x21b38, 0x1ccbd, 0x23736
         };
        private static readonly HashSet<int> DebuffCCleanseASAPPvPHS = new HashSet<int> { 
            0x19bcd, 0x1e201, 0xae1c, 0x25d, 0x7bad, 0x1696, 0x1cfab, 0x1fe38, 0xd1b, 0x355, 0x1b06a, 0xc93a, 0xa4d, 0x15a31, 0x1d120, 0x156c, 
            0x1c244, 0x1a85, 0x1ed93, 0x76, 0xef79, 0x6e70, 0xf119, 0xf154, 0x6e6f, 0xfa2c, 0x1fba, 0x1bc80, 0x1a247, 0x1c139, 0x4e62, 0x14303, 
            0x5e9, 0x2053c, 0x18d6, 0x250c, 0x764b, 0x154a4, 0x1966d, 0x1d079, 0x2856, 0x259d3, 0x1b934
         };
        private static readonly HashSet<int> DebuffDisarmHS = new HashSet<int> { 0xc56d, 0x2a4, 0x1cd4d, 0xca0a, 0x1ca78, 0x1edfa, 0xfa3a, 0x165fc };
        private static readonly HashSet<int> DebuffDoNotCleanseHS = new HashSet<int> { 0x213f8, 0x213fa, 0x213f4, 0x213f6, 0x759c, 0x21d71, 0x21dec, 0x21ded, 0x8862 };
        private static readonly HashSet<int> DebuffDoNotHealHS = new HashSet<int> { 0x2187d, 0x21874, 0x25d, 0x83fa, 0x1e177, 0x1e130, 0x1dc5d, 0x21890, 0x1de02, 0x22e11 };
        private static readonly HashSet<int> DebuffFearDurationHS = new HashSet<int> { 0x1696, 0x1cfab, 0x1fe38, 0x156c, 0x1b9a0, 0x1b96c, 0x147e, 0x501f, 0x1c244, 0xfa2c, 0x1fba, 0x1bc80, 0x2053c, 0x18d6, 0x154a4, 0x1966d };
        private static readonly HashSet<int> DebuffMagicCCDurationHS = new HashSet<int> { 
            710, 0x12bec, 0x1cb16, 0x19bcd, 0x1c428, 0x1e201, 0x1cdff, 0xae1c, 0x63, 0x25d, 0x7bad, 0x1696, 0x1cfab, 0x1fe38, 0x19c79, 0x1caaa, 
            0xd1b, 0x355, 0x1b06a, 0xa4d, 0xc93a, 0x15a31, 0x1d120, 0x156c, 0x1ed26, 0x1c244, 0x1a85, 0x76, 0xef79, 0x6e70, 0xf119, 0xf154, 
            0x6e6f, 0xfa2c, 0x1fba, 0x1bc80, 0x1a247, 0x1c139, 0x4e62, 0x14303, 0x5e9, 0x4c2f, 0x2053c, 0x18d6, 0x250c, 0x764b, 0x154a4, 0x1966d, 
            0xc557, 0x1d079, 0x2856, 0x259d3, 0x1a6a2
         };
        private static readonly HashSet<int> DebuffNeedTremor = new HashSet<int> { 
            0x1696, 0x1cfab, 0x1fe38, 0xa4d, 0x156c, 0x1b9a0, 0x1b96c, 0x147e, 0x501f, 0x1ed26, 0x1c244, 0x1a85, 0xfa2c, 0x1fba, 0x1bc80, 0x2053c, 
            0x18d6, 0x764b, 0x20448, 0x154a4, 0x1966d, 0x2856, 0x259d3
         };
        private static readonly HashSet<int> DebuffRootCanCleanseHS = new HashSet<int> { 
            0x17826, 0xfcb7, 0x153, 0x1bc6a, 0x4e07, 0x1ba7b, 0x1ba7b, 0x4af1, 0x8273, 0xf8c5, 0x7a, 0x1b065, 0x1549a, 0x1b2ec, 0x18fd7, 0x215ba, 
            0x1c1fd, 0x1669f, 0x1e20f, 0xd5b2, 0x1047
         };
        private static readonly HashSet<int> DebuffRootCanCloakHS = new HashSet<int> { 
            0x17826, 0xfcb7, 0x153, 0x1bc6a, 0x4e07, 0x1ba7b, 0x1ba7b, 0x4af1, 0x8273, 0xf8c5, 0x7a, 0x1b065, 0x1549a, 0x1b2ec, 0x18fd7, 0x1e20f, 
            0xd5b2, 0x1bee4, 0x1047
         };
        private static readonly HashSet<int> DebuffRootHS = new HashSet<int> { 
            0x17826, 0x1c7e2, 0xfcb7, 0x153, 0x1bc6a, 0x4e07, 0x1ba7b, 0x1ba7b, 0x4af1, 0x8273, 0xf8c5, 0x9c1d, 0x7a, 0x1b065, 0xd8f0, 0x1549a, 
            0x1b2ec, 0xb116, 0x160d7, 0x18fd7, 0x215ba, 0x332b, 0x1c1fd, 0xc445, 0x1669f, 0x1e20f, 0x1a42e, 0xd5b2, 0x1bee4, 0x1047
         };
        private static readonly HashSet<int> DebuffRootorSnareHS = new HashSet<int> { 
            0x17826, 0x1c7e2, 0xfcb7, 0x153, 0x1bc6a, 0x4e07, 0x1ba7b, 0x1ba7b, 0x4af1, 0x8273, 0xf8c5, 0x9c1d, 0x7a, 0x1b065, 0xd8f0, 0x1549a, 
            0x1b2ec, 0xb116, 0x160d7, 0x18fd7, 0x215ba, 0x332b, 0x1c1fd, 0xc445, 0x1669f, 0x1e20f, 0x1a42e, 0xd5b2, 0x1bee4, 0x1047, 0xc501, 0x1aedc, 
            0x891d, 0x13fc, 120, 0xd51, 0x472f, 0xb1d4, 0xc503, 0x1d9c8, 0x644, 0xf829, 0xc453, 0x6837, 0x1d390, 0x1c57f, 0x1e34f, 0xe10, 
            0x12ea6, 0x1e2c2, 0x1b9c4, 0xd574, 0x1f78, 0x74, 0x1f62, 0xae46, 0xefd2, 0x6b3, 0x35f2, 0xe344, 0x1cf39, 0x3c2f, 0x3023, 0x1c138, 
            0x4eca, 0xbb58, 0x7b65, 0x1fb83, 0xefcf, 0xc922, 0x1f335, 0x219a5
         };
        private static readonly HashSet<int> DebuffSilenceHS = new HashSet<int> { 
            0x1fa3d, 0x61d6, 0x13a63, 0x703a, 0x10e3b, 0xc5b5, 0x7cbf, 0x1be3e, 0x18ea3, 0x532, 0x1c446, 0x3c7f, 0x4842, 0xd6ed, 0x86ba, 0x13d6d, 
            0x1ba87, 0x1c7e5, 0x5ec3, 0x20539, 0xb974, 0x798d
         };
        private static readonly HashSet<int> DebuffSnareHS = new HashSet<int> { 
            0xc501, 0x1aedc, 0x891d, 0x13fc, 120, 0xd51, 0x472f, 0xb1d4, 0xc503, 0x1d9c8, 0x644, 0xf829, 0xc453, 0x6837, 0x1d390, 0x1c57f, 
            0x1e34f, 0xe10, 0x12ea6, 0x1e2c2, 0x1b9c4, 0xd574, 0x1f78, 0x74, 0x1f62, 0xae46, 0xefd2, 0x6b3, 0x35f2, 0xe344, 0x1cf39, 0x3c2f, 
            0x3023, 0x1c138, 0x4eca, 0xbb58, 0x7b65, 0x1fb83, 0xefcf, 0xc922, 0x1f335, 0x219a5, 0x11fd2
         };
        private static readonly HashSet<int> DebuffStunDurationHS = new HashSet<int> { 
            0x15ea6, 0x1bc89, 0x1918b, 0x1cb16, 0x1edf3, 0x1dd82, 0x1d260, 0x729, 0xae1c, 0xd602, 0x19c79, 0x1caaa, 0x16698, 0x355, 0x1b06a, 0x5f4a, 
            0x198, 0x1d255, 0x145b, 0x16695, 0x232d, 0x19092, 0x1c139, 0x14303, 0x764b, 0x20448, 0x1d079, 0x5045, 0x1a6a2, 0x1bd21
         };
        private static readonly HashSet<int> DebuffStunFearDurationHS = new HashSet<int> { 
            0x1d260, 0x729, 0xae1c, 0x7bad, 0x12ec1, 0x1696, 0x1cfab, 0x1fe38, 0x19c79, 0x1caaa, 0x355, 0x1b06a, 0x1b9a0, 0x1b96c, 0x147e, 0x501f, 
            0x5f4a, 0x198, 0x1d255, 0x145b, 0x16695, 0x232d, 0x19092, 0xfa2c, 0x1fba, 0x1bc80, 0x1ce49, 0x1c139, 0x14303, 0x764b, 0x20448, 0x154a4, 
            0x19d2b, 0x1a6a2
         };
        private static readonly HashSet<int> DoNotInterrupt = new HashSet<int> { 0xe40, 0x12fc7, 0xdd41, 0x193, 0x1bbf8, 0x5045, 0x1c25e, 0x1aacb };
        private static DateTime DoNotMove;
        private static WoWObject EnemyFreezingTrap;
        private static readonly Dictionary<ulong, DateTime> EnemyListCache = new Dictionary<ulong, DateTime>();
        private static DateTime EnemyListCacheClearLast;
        internal static int FailLoginAttempt;
        internal static DateTime FailLoginNextTime;
        private static readonly List<WoWUnit> FarFriendlyPlayers = new List<WoWUnit>();
        private static readonly List<WoWUnit> FarFriendlyUnits = new List<WoWUnit>();
        private static readonly List<WoWUnit> FarUnFriendlyPlayers = new List<WoWUnit>();
        private static readonly List<WoWUnit> FarUnFriendlyUnits = new List<WoWUnit>();
        private static readonly Dictionary<ulong, DateTime> FriendListCache = new Dictionary<ulong, DateTime>();
        private static DateTime FriendListCacheClearLast;
        private static DateTime GetPlayerFriendlyPurifySpiritLast;
        private static DateTime GetUnitHasMyEarthShieldLast;
        private static readonly HashSet<int> GhostWolfHS = new HashSet<int> { 0x4e62 };
        private static DateTime GlobalCheckTime;
        private static readonly HashSet<int> GroundingHS = new HashSet<int> { 
            0x76f3, 0x1c87a, 0x83fa, 0x153, 0x1b934, 0x18ea3, 0xc93a, 0xc931, 0x1f9c, 0x1f8ad, 0x76, 0x6e6f, 0x6e70, 0xf119, 0xef79, 0x4e62, 
            0x2ae, 0x1b5dc, 0xb60, 0x13352, 0x8862
         };
        private static WoWUnit GroundingTrapPlayer;
        private static readonly List<WoWPlayer> GroupHealingMembers = new List<WoWPlayer>();
        private static bool GroupHealingOn;
        private static string HasGlyph;
        private static string HasGlyphName;
        private static DateTime HealingWaveBaitInterruptLast;
        private static double HealWeightUnitHeal;
        private static readonly HashSet<int> HexImmuneAura = new HashSet<int> { 0x300, 0x156f, 0x30f, 0x42a, 0x8497, 0x9cb8, 0x611a, 0x190a0, 0x1908f, 0x1909e, 0x152c, 0x13cc9, 0x13cca, 0xa55, 0xb74c };
        private static readonly HashSet<WoWApplyAuraType> HS_HasAuraTypeDOT = new HashSet<WoWApplyAuraType> { 3, 0x59 };
        private static readonly HashSet<int> HS_NOTDOT = new HashSet<int> { 
            0x14b0b, 0x14b0a, 0x14b09, 0x173f7, 0x116a0, 0xb07d, 0x1d33b, 0x1ce0b, 0xd193, 0xe24e, 0x187f4, 0xe17b, 0xe17c, 0x139e2, 0x64ab, 0x177df, 
            0x17641, 0x2bbc, 0x1f3e5
         };
        private static readonly HashSet<string> ImportantTotemHS = new HashSet<string> { "Capacitor Totem", "Grounding Totem", "Stormlash Totem", "Windwalk Totem", "Earthbind Totem", "Earthgrab Totem", "Earth Elemental Totem", "Tremor Totem", "Fire Elemental Totem", "Spirit Link Totem", "Mana Tide Totem", "Healing Tide Totem" };
        private const string initVector = "www.tuanha.biz/l";
        private static readonly Dictionary<ulong, DateTime> InLineOfSpellSightCache = new Dictionary<ulong, DateTime>();
        private static readonly Dictionary<ulong, DateTime> InterruptonCooldownUnitList = new Dictionary<ulong, DateTime>();
        private static readonly HashSet<int> InterruptSpellHS = new HashSet<int> { 0x1998, 0x6e6, 0xb9a8, 0xb974, 0x177e7, 0x7cbf, 0xe28a, 0x85b, 0x1961f, 0x1c445, 0x23fa2, 0x86ba, 0x13c45, 0x1c7e1, 0x3c7f };
        private static readonly HashSet<int> InvulnerableHS = new HashSet<int> { 0x83fa, 0x4b3f, 0xb9e1, 0x282, 0xb17e, 0x6cb3 };
        private static readonly HashSet<int> InvulnerableRootandSnareHS = new HashSet<int> { 0xd017, 0xb74c, 0x414 };
        private static readonly HashSet<int> InvulnerableSpellHS = new HashSet<int> { 0xbe43, 0x79f8, 0x1c40b, 0x1ff2, 0x1bd6c, 0x5d70, 0x201c3 };
        private static readonly HashSet<int> InvulnerableStunHS = new HashSet<int> { 0xbe98, 0xb74c };
        private static bool IsOverrideModeOn;
        private static bool IsUsingAFKBot;
        private static TimeSpan ItemCooldownBack;
        private static readonly Dictionary<WoWItem, DateTime> ItemsCooldownCache = new Dictionary<WoWItem, DateTime>();
        private const int keysize = 0x100;
        public Keys KeyTwo;
        private static DateTime LastAoESearch;
        private static DateTime LastAutoFocus;
        private static DateTime LastAutoTarget;
        private static DateTime LastBreakCC;
        private static string LastCastSpell;
        private static DateTime LastCastTime;
        private static WoWUnit LastCastUnit;
        private static DateTime LastEarthShield;
        private static DateTime LastHealingSurge;
        private static DateTime LastInterrupt;
        private static DateTime LastLightningBoltFiller;
        private static DateTime LastRotationTime;
        private static DateTime LastSwitch;
        private static DateTime LastTrapEvent;
        private static DateTime LastWriteDebug;
        private static DateTime LastWriteLog;
        private static readonly string LocalFolder = Path.Combine(Utilities.AssemblyDirectory, @"Routines\" + CombatRoutineFolder);
        internal static bool LoginCheckVal = false;
        private static ulong MeGuid;
        private static double MeMaxHealth;
        internal const string Msp = "s";
        private static WoWUnit MyLastTarget;
        private static double MyLatency;
        private static readonly List<WoWUnit> NearbyFriendlyPlayers = new List<WoWUnit>();
        private static readonly List<WoWUnit> NearbyFriendlyUnits = new List<WoWUnit>();
        private static readonly List<WoWUnit> NearbyUnFriendlyPlayers = new List<WoWUnit>();
        private static readonly List<WoWUnit> NearbyUnFriendlyUnits = new List<WoWUnit>();
        private static readonly HashSet<uint> NeedHealUnitHS = new HashSet<uint> { 0xf3ea, 0x116ec, 0x115fe, 0x115fd, 0x116bd, 0x11a1a, 0x11a1b, 0x11a1d, 0x11a1c, 0x11894, 0x117b4, 0x117b4, 0x1193b, 0x1193c, 0x11738 };
        private static readonly HashSet<string> NeedPurgeASAPEleEnhHS = new HashSet<string> { 
            "Innervate", "Nature's Swiftness", "Predator's Swiftness", "Master's Call", "Arcane Power", "Alter Time", "Ice Barrier", "Icy Veins", "Mana Shield", "Fingers of Frost", "Presence of Mind", "Enveloping Mist", "Divine Plea", "Hand of Freedom", "Hand of Protection", "Hand of Sacrifice", 
            "Inner Focus", "Power Infusion", "Power Word: Shield", "Elemental Mastery", "Ghost Wolf", "Ancestral Swiftness", "Spiritwalker's Grace", "Sacrifice"
         };
        private static readonly HashSet<string> NeedPurgeASAPRestoHS = new HashSet<string> { 
            "Innervate", "Nature's Swiftness", "Predator's Swiftness", "Master's Call", "Arcane Power", "Alter Time", "Icy Veins", "Fingers of Frost", "Presence of Mind", "Divine Plea", "Hand of Freedom", "Hand of Protection", "Hand of Sacrifice", "Inner Focus", "Fear Ward", "Power Infusion", 
            "Elemental Mastery", "Spiritwalker's Grace", "Sacrifice"
         };
        private static DateTime NextSuppressMessage = DateTime.MinValue;
        private static readonly HashSet<string> OverrideToSpellHS = new HashSet<string> { "Purify Spirit", "Stormstrike" };
        private const string PATTERN = "/!svn/ver/(?'version'[0-9]*)/";
        private static WoWUnit PlayerFriendlyCleanseSpirit;
        private static WoWUnit PlayerFriendlyCleanseSpiritASAP;
        private static WoWUnit PlayerFriendlyPurifySpirit;
        private static WoWUnit PlayerFriendlyPurifySpiritASAP;
        private static WoWUnit PlayerHealingRain;
        private static readonly List<WoWPlayer> RaidPartyMembers = new List<WoWPlayer>();
        internal static string RealName;
        private const int RezMaxMobsNear = 0;
        private const int RezWaitDist = 20;
        private const int RezWaitTime = 10;
        private static readonly Random rnd = new Random();
        internal static string SafeCharName;
        private static readonly HashSet<int> SafeUsingCooldownHS = new HashSet<int> { 0x149d, 0xb74c };
        private static DateTime SearchFlagTime;
        private static DateTime spellCooldownBack;
        private static readonly Dictionary<string, DateTime> SpellsCooldownCache = new Dictionary<string, DateTime>();
        private static readonly HashSet<string> SpellsCooldownHS = new HashSet<string> { 
            "Arcane Torrent", "Berserking", "Blood Fury", "Cannibalize", "Darkflight", "Escape Artist", "Every Man for Himself", "Gift of the Naaru", "Rocket Jump", "Shadowmeld", "Stoneform", "War Stomp", "Will of the Forsaken", "Ascendance", "Astral Shift", "Ancestral Swiftness", 
            "Ancestral Guidance", "Call of the Elements", "Capacitor Totem", "Earth Elemental Totem", "Earthquake", "Earth Shock", "Earthbind Totem", "Earthgrab Totem", "Elemental Blast", "Elemental Mastery", "Grounding Totem", "Healing Rain", "Healing Stream Totem", "Healing Tide Totem", "Hex", "Feral Spirit", 
            "Fire Elemental Totem", "Healing Rain", "Lava Lash", "Mana Tide Totem", "Primal Strike", "Shamanistic Rage", "Riptide", "Spiritwalker's Grace", "Spirit Link Totem", "Stone Bulwark Totem", "Stormlash Totem", "Stormstrike", "Stormblast", "Thunderstorm", "Tremor Totem", "Unleash Elements", 
            "Windwalk Totem"
         };
        private static DateTime StopCastingCheckLast;
        private const string SVNURL = "https://tuanha.sourcerepo.com/tuanha/tuanhashamanspecialedition.5.4/";
        private static readonly Stopwatch sw = Stopwatch.StartNew();
        private static readonly Stopwatch swtotal = Stopwatch.StartNew();
        private static WoWUnit UnitAttackingMyPet;
        private static WoWUnit UnitAttackRestoAny;
        private static WoWUnit UnitAttackRTelluricCurrents;
        private static WoWUnit UnitAutoAttack;
        private static WoWPlayer UnitAutoRez;
        private static WoWUnit UnitBestFocus;
        private static WoWUnit UnitBestTarget;
        private static WoWUnit UnitBindElemental;
        private static WoWUnit UnitCapacitorEnemyDefault;
        private static WoWUnit UnitCapacitorEnemyDPS;
        private static WoWUnit UnitCapacitorEnemyHealer;
        private static WoWUnit UnitCapacitorEnemyPack;
        private static WoWUnit UnitDispellerAround;
        private static WoWUnit UnitEarthquake;
        private static WoWUnit UnitEarthShield;
        private static WoWUnit UnitFlameShock55447;
        private static WoWUnit UnitFlameShockAoE;
        private static WoWUnit UnitFlameShockRogueDruid;
        private static WoWUnit UnitFrostShockNearby;
        private static WoWUnit UnitGhostWolfCC;
        private static WoWUnit UnitGroundingCast;
        private static WoWUnit UnitGroundingLow;
        private static WoWUnit UnitHasMyEarthShield;
        private static WoWUnit UnitHaveMySacredShield;
        private static WoWUnit UnitHeal;
        private static bool UnitHealIsValid;
        private static WoWUnit UnitHex;
        private static WoWUnit UnitPurgeASAPResto;
        private static WoWUnit UnitPurgeNormalResto;
        private static WoWUnit UnitRiptide;
        private static WoWUnit UnitTankHasMyEarthShield;
        private static WoWUnit UnitTankToEarthShield;
        private static WoWUnit UnitThuderstormInterrupt;
        private static WoWUnit UnitWarStomp;
        private static WoWUnit UnitWindShear;
        private static int UseSpecialization;
        internal static string VersionBuild = "";
        private static DateTime WaterWalkingLast;
        private static WoWUnit WorthyTargetAttackingMe;
        private static bool WriteSW;

        private static Composite AncestralGuidance()
        {
            return new Decorator(ret => ((THSettings.Instance.AncestralGuidanceCooldown || (THSettings.Instance.AncestralGuidanceBurst && THSettings.Instance.Burst)) && Me.Combat) && CanCastCheck("Ancestral Guidance", true), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Ancestral Guidance", Me, "AncestralGuidance");
                return RunStatus.Failure;
            }));
        }

        private static bool AnyKeyPressed()
        {
            foreach (Keys keys in System.Enum.GetValues(typeof(Keys)))
            {
                if ((((((GetAsyncKeyState(keys) != 0) && (keys != Keys.Space)) && ((keys != Keys.LButton) && (keys != Keys.RButton))) && (((keys != Keys.None) && (keys != Keys.LWin)) && ((keys != Keys.RWin) && (keys != Keys.LShiftKey)))) && ((((keys != Keys.RShiftKey) && (keys != Keys.LControlKey)) && ((keys != Keys.RControlKey) && (keys != Keys.LMenu))) && (((keys != Keys.RMenu) && (keys != Keys.Tab)) && ((keys != Keys.Capital) && (keys != IndexToKeys(THSettings.Instance.StrafleLeft)))))) && ((((keys != IndexToKeys(THSettings.Instance.Forward)) && (keys != IndexToKeys(THSettings.Instance.StrafleRight))) && ((keys != IndexToKeys(THSettings.Instance.TurnLeft)) && (keys != IndexToKeys(THSettings.Instance.Backward)))) && (keys != IndexToKeys(THSettings.Instance.TurnRight))))
                {
                    return true;
                }
            }
            return false;
        }

        private static Composite AscendanceEle()
        {
            return new Decorator(ret => (((THSettings.Instance.AscendanceEleCooldown || (THSettings.Instance.AscendanceEleBurst && THSettings.Instance.Burst)) && (((!MeHasAura("Ascendance") && Me.Combat) && (CurrentTargetAttackable(40.0, false, false) && !CurrentTargetCheckInvulnerableMagic)) && (IsWorthyTarget(Me.CurrentTarget, 2.0, 0.5) || HaveWorthyTargetAttackingMe()))) && ((MyAuraTimeLeft("Flame Shock", Me.CurrentTarget) > 15000.0) && CanCastCheck("Ascendance", true))) && (GetSpellCooldown("Lava Burst", 0x7fffffff).TotalMilliseconds > 5000.0), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Ascendance", Me, "AscendanceEle");
                return RunStatus.Failure;
            }));
        }

        private static Composite AscendanceEnh()
        {
            return new Decorator(delegate (object ret) {
                if ((THSettings.Instance.AscendanceEnhCooldown || (THSettings.Instance.AscendanceEnhBurst && THSettings.Instance.Burst)) && (((Me.Combat && CurrentTargetAttackable(30.0, false, false)) && (!CurrentTargetCheckInvulnerablePhysic && (Me.ManaPercent > 20.0))) && ((!MeHasAura("Ascendance") && CanCastCheck("Ascendance", true)) && CanCastCheck("Primal Strike", false))))
                {
                    if (!IsWorthyTarget(Me.CurrentTarget, 2.0, 0.5))
                    {
                        return HaveWorthyTargetAttackingMe();
                    }
                    return true;
                }
                return false;
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Ascendance", Me, "AscendanceEnh");
                return RunStatus.Failure;
            }));
        }

        private static Composite AscendanceResto()
        {
            return new Decorator(ret => ((((THSettings.Instance.AscendanceResto && (HealWeightUnitHeal <= THSettings.Instance.AscendanceRestoHP)) && (UnitHealIsValid && UnitHeal.Combat)) && ((!UnitHeal.IsPet && !MeHasAura("Ascendance")) && (!Invulnerable(UnitHeal) && HaveDPSTarget(UnitHeal)))) && CanCastCheck("Ascendance", true)) && (CountUnitAscendanceResto(UnitHeal) >= THSettings.Instance.AscendanceRestoUnit), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Ascendance", Me, "AscendanceResto");
                return RunStatus.Failure;
            }));
        }

        private static Composite AstralShift()
        {
            return new Decorator(ret => ((THSettings.Instance.AstralShift && (Me.HealthPercent <= THSettings.Instance.AstralShiftHP)) && (Me.Combat && CanCastCheck("Astral Shift", false))) && HaveDPSTarget(Me), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Astral Shift", Me, "AstralShift");
            }));
        }

        private static void AttachCombatLogEventPvP()
        {
            if (!CombatLogAttachedPvP)
            {
                Lua.Events.AttachEvent("COMBAT_LOG_EVENT_UNFILTERED", new LuaEventHandlerDelegate(Classname.HandleCombatLogPvP));
                if (!Lua.Events.AddFilter("COMBAT_LOG_EVENT_UNFILTERED", "return (args[2] == 'SPELL_CAST_SUCCESS')"))
                {
                    Styx.Common.Logging.Write("ERROR: Could not add combat log event filter! - Performance may be horrible, and things may not work properly!");
                }
                Styx.Common.Logging.Write("Attached CombatLogAttachedPvP");
                CombatLogAttachedPvP = true;
            }
        }

        private static bool Attackable(WoWUnit target, int range)
        {
            return (((((target != null) && target.IsValid) && (target.Attackable && target.CanSelect)) && ((target.IsAlive && (GetDistance(target) <= range)) && (!Invulnerable(target) && !DebuffCCBreakonDamage(target)))) && (IsEnemy(target) && (((range <= 5) || (GetDistance(target) <= 5f)) || InLineOfSpellSightCheck(target))));
        }

        private static bool AttackableNoCC(WoWUnit target, int range)
        {
            return ((((target != null) && target.IsValid) && (target.Attackable && target.CanSelect)) && (((target.IsAlive && (((target.Distance - target.CombatReach) - 1.0) <= range)) && (!Invulnerable(target) && IsEnemy(target))) && (((range <= 5) || (GetDistance(target) <= 5f)) || InLineOfSpellSightCheck(target))));
        }

        private static bool AttackableNoCCLoS(WoWUnit target, int range)
        {
            return ((((target != null) && target.IsValid) && (target.Attackable && target.CanSelect)) && ((target.IsAlive && (GetDistance(target) <= range)) && (!Invulnerable(target) && IsEnemy(target))));
        }

        private static bool AttackableNoLoS(WoWUnit target, int range)
        {
            return ((((target != null) && target.IsValid) && (target.Attackable && target.CanSelect)) && ((target.IsAlive && (GetDistance(target) <= range)) && ((!Invulnerable(target) && !DebuffCCBreakonDamage(target)) && IsEnemy(target))));
        }

        private static Composite AttackResto()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.AttackResto && THSettings.Instance.AttackRestoFlameShock) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && ((CurrentTargetAttackable((double) ((int) SpellManager.Spells["Flame Shock"].MaxRange), false, false) && !CurrentTargetCheckInvulnerableMagic) && !MyAura("Flame Shock", Me.CurrentTarget))) && CanCastCheck("Flame Shock", false), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Flame Shock", Me.CurrentTarget, "AttackResto");
            })), new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.AttackResto || !THSettings.Instance.AttackRestoLavaBurst) || (!CurrentTargetAttackable(30.0, false, false) || CurrentTargetCheckInvulnerableMagic)) || (((HealWeightUnitHeal < THSettings.Instance.PriorityHeal) || (Me.ManaPercent < THSettings.Instance.AttackRestoMana)) && (SpellManager.Spells["Healing Wave"].CooldownTimeLeft.TotalMilliseconds <= 2000.0)))
                {
                    return false;
                }
                return CanCastCheck("Lava Burst", false);
            }, new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lava Burst", Me.CurrentTarget, "AttackResto");
            })), new Decorator(ret => (((THSettings.Instance.AttackResto && THSettings.Instance.AttackRestoElementalBlast) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && (CurrentTargetAttackable(40.0, false, false) && !CurrentTargetCheckInvulnerableMagic)) && CanCastCheck("Elemental Blast", false), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Elemental Blast", Me.CurrentTarget, "AttackResto");
            })), new Decorator(ret => (((THSettings.Instance.FlameShockEnh && (HealWeightUnitHeal >= THSettings.Instance.PriorityHeal)) && (HasGlyph.Contains("55447") && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && CanCastCheck("Flame Shock", false)) && GetUnitFlameShock55447(), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(UnitFlameShock55447);
                CastSpell("Flame Shock", UnitFlameShock55447, "FlameShock55447");
            })), new Decorator(ret => (((THSettings.Instance.AttackResto && THSettings.Instance.AttackRestoEarthShock) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && (CurrentTargetAttackable((double) ((int) SpellManager.Spells["Earth Shock"].MaxRange), false, false) && !CurrentTargetCheckInvulnerableMagic)) && CanCastCheck("Earth Shock", false), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Earth Shock", Me.CurrentTarget, "AttackResto");
            })), new Decorator(ret => (((THSettings.Instance.AttackResto && THSettings.Instance.AttackRestoChainLightning) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && (CurrentTargetAttackable(30.0, false, false) && !CurrentTargetCheckInvulnerableMagic)) && CanCastCheck("Chain Lightning", false), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Chain Lightning", Me.CurrentTarget, "AttackResto");
            })), new Decorator(ret => (((THSettings.Instance.AttackResto && THSettings.Instance.AttackRestoLightningBolt) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && (CurrentTargetAttackable(30.0, false, false) && !CurrentTargetCheckInvulnerableMagic)) && CanCastCheck("Lightning Bolt", false), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lightning Bolt", Me.CurrentTarget, "AttackResto");
            })), new Decorator(ret => (((THSettings.Instance.AttackRestoAny && THSettings.Instance.AttackRestoFlameShock) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && (CanCastCheck("Flame Shock", false) && GetUnitAttackRestoAny())) && !MyAura("Flame Shock", UnitAttackRestoAny), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(UnitAttackRestoAny);
                CastSpell("Flame Shock", UnitAttackRestoAny, "AttackRestoAny");
            })), new Decorator(delegate (object ret) {
                if ((!THSettings.Instance.AttackRestoAny || !THSettings.Instance.AttackRestoLavaBurst) || (!CanCastCheck("Lava Burst", false) || !GetUnitAttackRestoAny()))
                {
                    return false;
                }
                return ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana)) || (SpellManager.Spells["Healing Wave"].CooldownTimeLeft.TotalMilliseconds > 2000.0);
            }, new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(UnitAttackRestoAny);
                CastSpell("Lava Burst", UnitAttackRestoAny, "AttackRestoAny");
            })), new Decorator(ret => (((THSettings.Instance.AttackRestoAny && THSettings.Instance.AttackRestoElementalBlast) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && CanCastCheck("Elemental Blast", false)) && GetUnitAttackRestoAny(), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(UnitAttackRestoAny);
                CastSpell("Elemental Blast", UnitAttackRestoAny, "AttackResto");
            })), new Decorator(ret => (((THSettings.Instance.AttackRestoAny && THSettings.Instance.AttackRestoEarthShock) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && CanCastCheck("Earth Shock", false)) && GetUnitAttackRestoAny(), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(UnitAttackRestoAny);
                CastSpell("Earth Shock", UnitAttackRestoAny, "AttackRestoAny");
            })), new Decorator(ret => (((THSettings.Instance.AttackRestoAny && THSettings.Instance.AttackRestoChainLightning) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && CanCastCheck("Chain Lightning", false)) && GetUnitAttackRestoAny(), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(UnitAttackRestoAny);
                CastSpell("Chain Lightning", UnitAttackRestoAny, "AttackRestoAny");
            })), new Decorator(ret => (((THSettings.Instance.AttackRestoAny && THSettings.Instance.AttackRestoLightningBolt) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent >= THSettings.Instance.AttackRestoMana))) && CanCastCheck("Lightning Bolt", false)) && GetUnitAttackRestoAny(), new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(UnitAttackRestoAny);
                CastSpell("Lightning Bolt", UnitAttackRestoAny, "AttackRestoAny");
            })) });
        }

        private static Composite AutoAttack()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if ((THSettings.Instance.AutoAttack && MeHasAura("Ghost Wolf")) && CurrentTargetAttackable(5.0, false, false))
                {
                    CancelAura("Ghost Wolf", Me);
                    SpellManager.Cast("Auto Attack");
                    return RunStatus.Failure;
                }
                if (((THSettings.Instance.AutoAttack && (AutoAttackLast < DateTime.Now)) && (CurrentTargetAttackable(10.0, false, false) || (CurrentTargetAttackable(30.0, false, false) && SpellManager.HasSpell("Stormblast")))) && !Me.IsAutoAttacking)
                {
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "AutoAttack");
                    SpellManager.Cast("Auto Attack");
                    AutoAttackLast = DateTime.Now + TimeSpan.FromMilliseconds((double) Me.Inventory.Equipped.MainHand.ItemInfo.WeaponSpeed);
                    return RunStatus.Failure;
                }
                return RunStatus.Failure;
            });
        }

        private static Composite AutoAttackOffTarget()
        {
            return new Decorator(ret => ((((UseSpecialization == 2) && (AutoAttackLast < DateTime.Now)) && (!CurrentTargetAttackable(10.0, false, false) && (Me.CurrentTarget != null))) && ((Me.Combat && (Me.Inventory.Equipped.MainHand != null)) && ((Me.ManaPercent < 70.0) && CanCastCheck("Auto Attack", false)))) && GetUnitAutoAttack(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Auto Attack", UnitAutoAttack, "AutoAttack Enh Gain Mana");
                AutoAttackLast = DateTime.Now + TimeSpan.FromMilliseconds((double) Me.Inventory.Equipped.MainHand.ItemInfo.WeaponSpeed);
                Me.TargetLastTarget();
                return RunStatus.Failure;
            }));
        }

        private static Composite AutoRez()
        {
            Composite[] children = new Composite[] { new Styx.TreeSharp.Action(delegate (object param0) {
                if (THSettings.Instance.AutoMove && ((UnitAutoRez.Distance > 40.0) || !InLineOfSpellSightCheck(UnitAutoRez)))
                {
                    Navigator.MoveTo(UnitAutoRez.Location);
                }
                else if ((UnitAutoRez.Distance <= 40.0) && UnitAutoRez.InLineOfSight)
                {
                    if (IsMoving(Me))
                    {
                        Navigator.PlayerMover.MoveStop();
                    }
                    CastSpell("Ancestral Spirit", UnitAutoRez, "Ancestral Spirit");
                    AutoRezListCacheAdd(UnitAutoRez, 20);
                }
            }) };
            return new Decorator(ret => ((THSettings.Instance.AutoRez && !Me.Combat) && CanCastCheck("Ancestral Spirit", false)) && GetUnitAutoRez(), new PrioritySelector(children));
        }

        private static void AutoRezListCacheAdd(WoWUnit unit, int expireSeconds = 20)
        {
            if (!AutoRezListCache.ContainsKey(unit.Guid))
            {
                AutoRezListCache.Add(unit.Guid, DateTime.Now + TimeSpan.FromSeconds((double) expireSeconds));
            }
        }

        private static void AutoRezListCacheClear()
        {
            foreach (ulong num in (from unit in AutoRezListCache
                where unit.Value < DateTime.Now
                select unit.Key).ToList<ulong>())
            {
                AutoRezListCache.Remove(num);
            }
        }

        private static Composite AutoSetFocus()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (THSettings.Instance.AutoSetFocus && (LastAutoFocus <= DateTime.Now))
                {
                    if (((Me.CurrentTarget != null) && (Me.FocusedUnit == null)) && GetBestFocus())
                    {
                        UnitBestFocus.Target();
                        Lua.DoString("RunMacroText('/focus');", "WoW.lua");
                        Me.SetFocus(UnitBestFocus);
                        Me.TargetLastTarget();
                        Styx.Common.Logging.Write("Set Focus: " + UnitBestFocus.SafeName);
                        LastAutoFocus = DateTime.Now + TimeSpan.FromMilliseconds(2000.0);
                        return RunStatus.Failure;
                    }
                    if ((((UseSpecialization != 3) && (Me.CurrentTarget != null)) && (Me.FocusedUnit != null)) && (((Me.CurrentTarget == Me.FocusedUnit) || !AttackableNoCCLoS(Me.FocusedUnit, 60)) || (((TalentSort(Me.FocusedUnit) < 4) && GetBestFocus()) && (TalentSort(UnitBestFocus) == 4))))
                    {
                        Styx.Common.Logging.Write("Clear Focus");
                        Lua.DoString("RunMacroText('/clearfocus');", "WoW.lua");
                        Me.SetFocus((ulong) 0L);
                        LastAutoFocus = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
                    }
                }
                return RunStatus.Failure;
            });
        }

        private static Composite AutoTargetMelee()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (THSettings.Instance.AutoTarget && (LastAutoTarget <= DateTime.Now))
                {
                    if ((BasicCheck(Me.CurrentTarget) && !CurrentTargetAttackableNoLoS(50.0)) && (GetBestTarget() && (Me.CurrentTarget != UnitBestTarget)))
                    {
                        UnitBestTarget.Target();
                        Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "Switch to Best Unit");
                        LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
                        return RunStatus.Failure;
                    }
                    if (!BasicCheck(Me.CurrentTarget) && GetBestTarget())
                    {
                        UnitBestTarget.Target();
                        Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "Target  Best Unit");
                        LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
                        return RunStatus.Failure;
                    }
                    LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
                }
                return RunStatus.Failure;
            });
        }

        private static Composite AutoTargetRange()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (THSettings.Instance.AutoTarget && (LastAutoTarget <= DateTime.Now))
                {
                    if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
                    {
                        if ((BasicCheck(Me.CurrentTarget) && !CurrentTargetAttackableNoLoS(50.0)) && (GetBestTarget() && (Me.CurrentTarget != UnitBestTarget)))
                        {
                            UnitBestTarget.Target();
                            Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "Switch to Best Unit");
                            LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
                            return RunStatus.Failure;
                        }
                        if (!BasicCheck(Me.CurrentTarget) && GetBestTarget())
                        {
                            UnitBestTarget.Target();
                            Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "Target  Best Unit");
                            LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
                            return RunStatus.Failure;
                        }
                    }
                    else if (GetBestTargetRange() && (Me.CurrentTarget != UnitBestTarget))
                    {
                        UnitBestTarget.Target();
                        Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "Switch to Best Unit Ele");
                        LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
                        return RunStatus.Failure;
                    }
                    LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
                }
                return RunStatus.Failure;
            });
        }

        private static bool BasicCheck(WoWUnit target)
        {
            return (((target != null) && target.IsValid) && target.IsAlive);
        }

        private static Composite BindElemental()
        {
            return new Decorator(ret => ((THSettings.Instance.BindElemental && ((UseSpecialization != 2) || ((UseSpecialization == 2) && (HealWeightUnitHeal >= THSettings.Instance.PriorityHeal)))) && (CanCastCheck("Bind Elemental", false) && !HasUnitBindElemental())) && GetUnitUnitBindElemental(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Bind Elemental", UnitBindElemental, "BindElemental");
            }));
        }

        private static bool BuffBurst(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => BuffBurstHS.Contains(aura.SpellId));
        }

        private static bool BuffEnrage(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!BuffEnrageHS.Contains(aura.SpellId))
                {
                    return (aura.Spell.DispelType == WoWDispelType.Enrage);
                }
                return true;
            });
        }

        private static bool BuffHeal(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => BuffHealHS.Contains(aura.SpellId));
        }

        private static WoWPoint CalculateDropLocation(WoWUnit target)
        {
            WoWPoint location;
            if ((!target.IsMoving || target.MovementInfo.MovingBackward) || DebuffRoot(target))
            {
                location = target.Location;
            }
            else if (DebuffSnare(target))
            {
                location = FindGround(WoWMathHelper.CalculatePointBehind(target.Location, target.Rotation, -3f), 10);
            }
            else
            {
                location = FindGround(WoWMathHelper.CalculatePointBehind(target.Location, target.Rotation, -6f), 10);
            }
            if (location.Distance(Me.Location) > 40f)
            {
                location = FindGround(WoWMathHelper.CalculatePointFrom(Me.Location, location, 39f), 10);
            }
            return location;
        }

        private static bool CanCastCheck(string spellName, bool IsOffGCDSpell = false)
        {
            WoWSpell spell;
            if (!SpellManager.HasSpell(spellName))
            {
                return false;
            }
            SpellsCooldownCacheClear();
            if (SpellsCooldownCache.ContainsKey(spellName))
            {
                return false;
            }
            if (OverrideToSpellHS.Contains(spellName))
            {
                spell = WoWSpell.FromId(OverrideToSpellId(spellName));
            }
            else
            {
                spell = SpellManager.Spells[spellName];
            }
            return CanCastCheckSpell(spell, IsOffGCDSpell);
        }

        private static bool CanCastCheckSpell(WoWSpell spell, bool IsOffGCDSpell)
        {
            if ((!Me.CurrentMap.IsArena && !Me.CurrentMap.IsBattleground) || (((spell.ToString() == "Thunderstorm") || (spell.ToString() == "Shamanistic Rage")) || ((spell.ToString() == "Tremor Totem") || !DebuffCC(Me))))
            {
                double powerCost;
                double castTime;
                if ((UseSpecialization == 2) && (spell.School == WoWSpellSchool.Nature))
                {
                    powerCost = spell.PowerCost - (spell.PowerCost * (MyAuraStackCount(0xd239, Me) / 5.0));
                }
                else
                {
                    powerCost = spell.PowerCost;
                }
                if (Me.CurrentMana < powerCost)
                {
                    return false;
                }
                if ((((!IsMoving(Me) || (spell.ToString() == "Lightning Bolt")) || MeHasAura("Spiritwalker's Grace")) || ((spell.ToString() == "Lava Burst") && MeHasAura(0x12fc2))) || (spell.School.ToString().Contains("Nature") && (MeHasAura(0x3f3c) || ((UseSpecialization == 2) && (MyAuraStackCount(0xd239, Me) > 4.0)))))
                {
                    castTime = 0.0;
                }
                else
                {
                    castTime = spell.CastTime;
                }
                if (castTime <= 0.0)
                {
                    if ((IsOffGCDSpell || !Me.IsCasting) || ((Me.IsCasting && (Me.CurrentCastTimeLeft.TotalMilliseconds <= MyLatency)) && (Me.CurrentChannelTimeLeft.TotalMilliseconds <= MyLatency)))
                    {
                        if (IsOffGCDSpell)
                        {
                            spellCooldownBack = (DateTime.Now + spell.CooldownTimeLeft) - TimeSpan.FromMilliseconds(1500.0);
                        }
                        else
                        {
                            spellCooldownBack = (DateTime.Now + spell.CooldownTimeLeft) - TimeSpan.FromMilliseconds(MyLatency);
                        }
                        if (spellCooldownBack <= DateTime.Now)
                        {
                            return true;
                        }
                    }
                    SpellsCooldownCacheAdd(spell.ToString(), spellCooldownBack);
                }
            }
            return false;
        }

        private static void CancelAura(int aura, WoWUnit target)
        {
            WoWAura auraById = target.GetAuraById(aura);
            if ((auraById != null) && auraById.Cancellable)
            {
                auraById.TryCancelAura();
            }
        }

        private static void CancelAura(string aura, WoWUnit target)
        {
            WoWAura auraByName = target.GetAuraByName(aura);
            if ((auraByName != null) && auraByName.Cancellable)
            {
                auraByName.TryCancelAura();
            }
        }

        private static bool CanHex(WoWUnit target)
        {
            return target.GetAllAuras().All<WoWAura>(aura => !HexImmuneAura.Contains(aura.SpellId));
        }

        private static bool CanUseCheck(WoWItem Item)
        {
            ItemsCooldownCacheClear();
            if (!ItemsCooldownCache.ContainsKey(Item))
            {
                ItemCooldownBack = GetItemCooldown(Item);
                if (ItemCooldownBack.TotalMilliseconds <= 0.0)
                {
                    return true;
                }
                ItemsCooldownCacheAdd(Item, DateTime.Now + ItemCooldownBack);
            }
            return false;
        }

        private static bool CanUseEquippedItem(WoWItem item)
        {
            if (string.IsNullOrEmpty(Lua.GetReturnVal<string>("return GetItemSpell(" + item.Entry + ")", 0)))
            {
                return false;
            }
            return (item.Usable && (item.Cooldown <= 0f));
        }

        private static Composite Capacitor()
        {
            return new Decorator(ret => ((THSettings.Instance.CapacitorProject && THSettings.Instance.CapacitorProjectGroup) && (!MyTotemAirCheck(Me, 60) && CanCastCheck("Capacitor Totem", false))) && GetUnitCapacitorEnemyPack(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Capacitor Totem", UnitCapacitorEnemyPack, "CapacitorEnemyPack");
            }));
        }

        private static void CapacitorProjection(int MsLeft)
        {
            if ((THSettings.Instance.CapacitorProjection && SpellManager.HasSpell("Totemic Projection")) && ((MyTotemCheck("Capacitor Totem", Me, 100) && (CapacitorTotemCastTime() <= MsLeft)) && (SpellManager.Spells["Totemic Projection"].CooldownTimeLeft.TotalMilliseconds <= MsLeft)))
            {
                CapacitorTarget = null;
                CapacitorProjectionPurpose = null;
                if ((THSettings.Instance.CapacitorProject && THSettings.Instance.CapacitorProjectFocus) && (BasicCheck(Me.FocusedUnit) && InLineOfSpellSightCheck(Me.FocusedUnit)))
                {
                    CapacitorTarget = Me.FocusedUnit;
                    CapacitorProjectionPurpose = "Capacitor Focus";
                }
                else if ((THSettings.Instance.CapacitorProject && THSettings.Instance.CapacitorProjectTarget) && (BasicCheck(Me.CurrentTarget) && InLineOfSpellSightCheck(Me.CurrentTarget)))
                {
                    CapacitorTarget = Me.CurrentTarget;
                    CapacitorProjectionPurpose = "Capacitor Target";
                }
                else if ((THSettings.Instance.CapacitorProject && THSettings.Instance.CapacitorProjectHealer) && GetUnitCapacitorEnemyHealer())
                {
                    CapacitorTarget = UnitCapacitorEnemyHealer;
                    CapacitorProjectionPurpose = "Capacitor Enemy Healer";
                }
                else if ((THSettings.Instance.CapacitorProject && THSettings.Instance.CapacitorProjectDPS) && GetUnitCapacitorEnemyDPS())
                {
                    CapacitorTarget = UnitCapacitorEnemyDPS;
                    CapacitorProjectionPurpose = "Capacitor Enemy DPS";
                }
                if (!BasicCheck(CapacitorTarget) && GetUnitCapacitorEnemyDefault())
                {
                    CapacitorTarget = UnitCapacitorEnemyDefault;
                    CapacitorProjectionPurpose = "Capacitor on Enemy by Default";
                }
                if (!BasicCheck(CapacitorTarget))
                {
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "Can't Find Suitable Capacitor Target");
                }
                else if (MyTotemCheck("Capacitor Totem", CapacitorTarget, 3))
                {
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "Capacitor Totem Already Near Target. No Projection needed");
                }
                else
                {
                    Styx.Common.Logging.Write("Trying to Capacitor Projection on {0} purpose {1}", new object[] { CapacitorTarget.SafeName, CapacitorProjectionPurpose });
                    if (Me.IsCasting)
                    {
                        SpellManager.StopCasting();
                    }
                    CastSpell("Totemic Projection", Me, "Totemic Projection Capacitor Totem");
                    ObjectManager.Update();
                    SpellManager.ClickRemoteLocation(CapacitorTarget.Location);
                }
            }
        }

        private static void CapacitorTestPosition()
        {
            if ((BasicCheck(Me.CurrentTarget) && MyTotemCheck("Searing Totem", Me, 40)) && CanCastCheck("Totemic Projection", true))
            {
                if (Me.IsCasting)
                {
                    SpellManager.StopCasting();
                }
                CastSpell("Totemic Projection", Me, "Totemic Projection");
                ObjectManager.Update();
                WoWPoint location = new WoWPoint(Me.CurrentTarget.X + THSettings.Instance.SpiritLinkUnit, Me.CurrentTarget.Y + THSettings.Instance.AscendanceRestoUnit, Me.CurrentTarget.Z);
                SpellManager.ClickRemoteLocation(location);
            }
        }

        private static double CapacitorTotemCastTime()
        {
            for (int i = 0; i < 4; i++)
            {
                if ((Me.Totems[i].Unit != null) && (Me.Totems[i].Unit.Name == "Capacitor Totem"))
                {
                    return Me.Totems[i].Unit.CurrentCastTimeLeft.TotalMilliseconds;
                }
            }
            return 10000.0;
        }

        private static void CastSpell(string spellName, WoWUnit target, string reason = "")
        {
            SpellManager.Cast(spellName, target);
            LastCastSpell = spellName;
            LastCastUnit = target;
            LastCastTime = DateTime.Now;
            if (THSettings.Instance.AutoWriteLog && (LastWriteLog <= DateTime.Now))
            {
                LastWriteLog = DateTime.Now + TimeSpan.FromMilliseconds(MyLatency);
                if (((spellName == "Wind Shear") || (spellName == "Grounding Totem")) || ((spellName == "Capacitor Totem") || (spellName == "Hex")))
                {
                    colorlog = Colors.GhostWhite;
                }
                else if (target == Me)
                {
                    colorlog = Colors.GreenYellow;
                }
                else if (target == Me.CurrentTarget)
                {
                    colorlog = Colors.Yellow;
                }
                else
                {
                    colorlog = Colors.YellowGreen;
                }
                Styx.Common.Logging.Write(colorlog, string.Concat(new object[] { DateTime.Now.ToString("ss:fff"), " HP: ", Math.Round(Me.HealthPercent), "% Mana: ", Math.Round(Me.ManaPercent), " ", target.SafeName, " ", Math.Round(target.Distance, 2), "y ", Math.Round(target.HealthPercent), "% hp ", spellName, " (", reason, ")" }));
            }
        }

        private static Composite ChainHeal()
        {
            return new Decorator(ret => (((THSettings.Instance.ChainHeal && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.ChainHealHP) && SpellManager.HasSpell("Chain Heal"))) && ((Me.CurrentMana > (SpellManager.Spells["Chain Heal"].PowerCost * 2)) && CanCastCheck("Chain Heal", false))) && (CountUnitChainHeal() >= THSettings.Instance.ChainHealUnit), new Styx.TreeSharp.Action(delegate (object param0) {
                UnleaseElementEarthLiving(THSettings.Instance.UnleashElementsCH, UnitHeal);
                CastSpell("Chain Heal", UnitHeal, "ChainHeal");
            }));
        }

        private static Composite ChainLightning5MW()
        {
            return new Decorator(ret => (((THSettings.Instance.ChainLightningEnh && CurrentTargetAttackable(30.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && (MyAuraStackCount(0xd239, Me) > 4.0))) && FacingOverride(Me.CurrentTarget)) && CanCastCheck("Chain Lightning", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Chain Lightning", Me.CurrentTarget, "ChainLightning5MW");
            }));
        }

        private static Composite ChainLightningEle()
        {
            return new Decorator(ret => (((THSettings.Instance.ChainLightningEle && CurrentTargetAttackable(30.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget))) && (((Me.ManaPercent >= THSettings.Instance.EleAoEMana) && (CountEnemyNear(Me.CurrentTarget, 15f) >= THSettings.Instance.ChainLightningEleUnit)) && (CanCastCheck("Chain Lightning", false) && !CanCastCheck("Lava Burst", false)))) && !CanCastCheck("Elemental Blast", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Chain Lightning", Me.CurrentTarget, "ChainLightningEle");
            }));
        }

        private static Composite ChainLightningEleAoE()
        {
            return new Decorator(ret => (((THSettings.Instance.ChainLightningEle && CurrentTargetAttackable(30.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget))) && ((Me.ManaPercent >= THSettings.Instance.EleAoEMana) && (CountEnemyNear(Me.CurrentTarget, 15f) >= THSettings.Instance.ChainLightningEleUnit))) && CanCastCheck("Chain Lightning", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Chain Lightning", Me.CurrentTarget, "ChainLightningEleAoE");
            }));
        }

        private static void ChatFilter(Chat.ChatSimpleMessageEventArgs e)
        {
            if (THSettings.Instance.FlagReturnorPickup && (((Battlegrounds.Current == BattlegroundType.WSG) || (Battlegrounds.Current == BattlegroundType.TP)) || (Battlegrounds.Current == BattlegroundType.EotS)))
            {
                if (e.Message.Contains("Flag was dropped by"))
                {
                    SearchFlagTime = DateTime.Now + TimeSpan.FromSeconds(10.0);
                }
                else if ((SearchFlagTime > DateTime.Now) && e.Message.Contains("Flag was returned to its base by"))
                {
                    SearchFlagTime = DateTime.Now - TimeSpan.FromSeconds(10.0);
                }
            }
        }

        private static Composite CleanseSpiritFriendlyASAPEle()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (THSettings.Instance.CleanseSpiritEle && GetPlayerFriendlyCleanseSpiritASAP()) && CanCastCheck("Cleanse Spirit", true), new Styx.TreeSharp.Action(delegate (object param0) {
                SpellManager.StopCasting();
                CastSpell("Cleanse Spirit", PlayerFriendlyCleanseSpiritASAP, "CleanseSpiritFriendlyASAPEle");
            })) });
        }

        private static Composite CleanseSpiritFriendlyASAPEnh()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (THSettings.Instance.CleanseSpiritEnh && GetPlayerFriendlyCleanseSpiritASAP()) && CanCastCheck("Cleanse Spirit", true), new Styx.TreeSharp.Action(delegate (object param0) {
                SpellManager.StopCasting();
                CastSpell("Cleanse Spirit", PlayerFriendlyCleanseSpiritASAP, "CleanseSpiritFriendlyASAPEnh");
            })) });
        }

        private static Composite CleanseSpiritFriendlyEle()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => ((THSettings.Instance.CleanseSpiritEle && (Me.ManaPercent > THSettings.Instance.PriorityHeal)) && GetPlayerFriendlyCleanseSpirit()) && CanCastCheck("Cleanse Spirit", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SpellManager.StopCasting();
                CastSpell("Cleanse Spirit", PlayerFriendlyCleanseSpirit, "CleanseSpiritEle");
            })) });
        }

        private static Composite CleanseSpiritFriendlyEnh()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => ((THSettings.Instance.CleanseSpiritEnh && (Me.ManaPercent > THSettings.Instance.PriorityHeal)) && CanCastCheck("Cleanse Spirit", false)) && GetPlayerFriendlyCleanseSpirit(), new Styx.TreeSharp.Action(delegate (object param0) {
                SpellManager.StopCasting();
                CastSpell("Cleanse Spirit", PlayerFriendlyCleanseSpirit, "CleanseSpiritEnh");
            })) });
        }

        private static double CountDebuff(WoWUnit u)
        {
            return (double) u.Debuffs.Values.Count<WoWAura>(delegate (WoWAura debuff) {
                if (debuff.Spell.DispelType != WoWDispelType.Magic)
                {
                    return (debuff.Spell.DispelType == WoWDispelType.Curse);
                }
                return true;
            });
        }

        private static double CountDebuffAll(WoWUnit u)
        {
            if (((u != null) && u.IsValid) && u.IsAlive)
            {
                return (double) u.Debuffs.Values.Count<WoWAura>();
            }
            return 0.0;
        }

        private static double CountDebuffCurse(WoWUnit target)
        {
            return (double) target.Debuffs.Values.Count<WoWAura>(debuff => (debuff.Spell.DispelType == WoWDispelType.Curse));
        }

        private static double CountDebuffMagic(WoWUnit u)
        {
            if (((u == null) || !u.IsValid) || !u.IsAlive)
            {
                return 0.0;
            }
            return (double) u.Debuffs.Values.Count<WoWAura>(debuff => (debuff.Spell.DispelType == WoWDispelType.Magic));
        }

        private static double CountDebuffRootandSnareMechanic(WoWUnit u)
        {
            if (((u == null) || !u.IsValid) || !u.IsAlive)
            {
                return 0.0;
            }
            return (double) u.GetAllAuras().Count<WoWAura>(delegate (WoWAura debuff) {
                if (debuff.Spell.Mechanic != WoWSpellMechanic.Snared)
                {
                    return (debuff.Spell.Mechanic == WoWSpellMechanic.Rooted);
                }
                return true;
            });
        }

        private static double CountEnemyNear(WoWUnit unitCenter, float distance)
        {
            return (double) FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(delegate (WoWUnit unit) {
                if ((!(Me.CurrentMap.Name == "Proving Grounds") && !IsDummy(unit)) && ((!unit.Combat || (unit.MaxHealth <= (MeMaxHealth * 0.2))) || (!unit.GotTarget || !FarFriendlyUnits.Contains(unit.CurrentTarget))))
                {
                    return false;
                }
                return (GetDistance(unitCenter, unit) <= distance);
            });
        }

        private static double CountEnemyPlayerNearCapacitor(WoWObject unitCenter)
        {
            return (double) NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => ((((unitCenter.Location.Distance(unit.Location) <= 8f) && !Invulnerable(unit)) && !InvulnerableSpell(unit)) && !DebuffCC(unit)));
        }

        private static double CountEnemyTargettingUnit(WoWUnit target, float distance)
        {
            return (double) FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(delegate (WoWUnit unit) {
                if (((!unit.IsValid || (GetDistance(unit) >= distance)) || ((unit.Level > (target.Level + 3)) || (unit.MaxHealth <= (MeMaxHealth * 0.3)))) || ((unit.CurrentTarget != target) || DebuffCC(unit)))
                {
                    return false;
                }
                return ((target != Me) || ((target == Me) && InLineOfSpellSightCheck(unit)));
            });
        }

        private static int CountFriendDPSTarget(WoWUnit target)
        {
            Func<WoWUnit, bool> predicate = null;
            if (!Me.CurrentMap.IsArena && !Me.CurrentMap.IsBattleground)
            {
                return NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => (unit.CurrentTarget == target));
            }
            if (predicate == null)
            {
                predicate = delegate (WoWUnit unit) {
                    if (unit.CurrentTarget != target)
                    {
                        return false;
                    }
                    return (((TalentSort(unit) >= 2) && (TalentSort(unit) <= 3)) && (unit.Location.Distance(target.Location) < 40f)) || ((TalentSort(unit) == 1) && (unit.Location.Distance(target.Location) < 15f));
                };
            }
            return NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(predicate);
        }

        private static int CountMagicBuffPurge(WoWUnit target)
        {
            return target.GetAllAuras().Count<WoWAura>(a => ((a.IsActive && !a.IsHarmful) && (a.Spell.DispelType == WoWDispelType.Magic)));
        }

        private static int CountMeleeDPSTarget(WoWUnit target)
        {
            Func<WoWUnit, bool> predicate = null;
            Func<WoWUnit, bool> func2 = null;
            if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
            {
                if (predicate == null)
                {
                    predicate = delegate (WoWUnit unit) {
                        if (((!unit.IsValid || (unit.CurrentTarget != target)) || ((TalentSort(unit) != 1) || (unit.Location.Distance(target.Location) >= 15f))) || DebuffCC(unit))
                        {
                            return false;
                        }
                        return (target != Me) || ((target == Me) && InLineOfSpellSightCheck(unit));
                    };
                }
                return NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(predicate);
            }
            if (func2 == null)
            {
                func2 = unit => ((unit.IsValid && (unit.CurrentTarget == target)) && (unit.Location.Distance(target.Location) < 15f)) && !DebuffCC(unit);
            }
            return FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(func2);
        }

        private static int CountNearEnemyEarthbind(WoWUnit target, int dist)
        {
            return NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => ((((((unit.Combat && (TalentSort(unit) == 1)) && (unit.GotTarget && NearbyFriendlyPlayers.Contains(unit.CurrentTarget))) && (unit.MaxHealth > (MeMaxHealth * 0.5))) && ((GetDistance(target, unit) <= dist) || (((GetDistance(target, unit) <= (dist + 10)) && unit.IsMoving) && unit.IsSafelyFacing(target)))) && !InvulnerableRootandSnare(unit)) && !DebuffRootorSnare(unit)));
        }

        private static int CountNearEnemyEarthbindNoRooted(WoWUnit target, int dist)
        {
            return NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => ((((unit.Combat && (TalentSort(unit) == 1)) && (unit.GotTarget && NearbyFriendlyPlayers.Contains(unit.CurrentTarget))) && (((unit.MaxHealth > (MeMaxHealth * 0.5)) && (GetDistance(target, unit) <= dist)) && !InvulnerableRootandSnare(unit))) && !DebuffRoot(unit)));
        }

        private static int CountPhysicDPSTarget(WoWUnit target)
        {
            Func<WoWUnit, bool> predicate = null;
            Func<WoWUnit, bool> func2 = null;
            if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
            {
                if (predicate == null)
                {
                    predicate = unit => (((unit.IsValid && (unit.CurrentTarget == target)) && (((TalentSort(unit) == 2) && (unit.Location.Distance(target.Location) < 40f)) || ((TalentSort(unit) == 1) && (unit.Location.Distance(target.Location) < 25f)))) && !DebuffCC(unit)) && ((target != Me) || ((target == Me) && InLineOfSpellSightCheck(unit)));
                }
                return NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(predicate);
            }
            if (func2 == null)
            {
                func2 = unit => ((unit.IsValid && (unit.CurrentTarget == target)) && (unit.Location.Distance(target.Location) < 15f)) && !DebuffCC(unit);
            }
            return FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(func2);
        }

        private static int CountUnitAscendanceResto(WoWUnit unitCenter)
        {
            return NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => (((HealWeight(unit) < 80.0) && (HealWeight(unit) < (THSettings.Instance.AscendanceRestoHP + 20))) && (unitCenter.Location.Distance(unit.Location) <= 20f)));
        }

        private static double CountUnitChainHeal()
        {
            return (double) NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(delegate (WoWUnit unit) {
                if ((unit.Location.Distance(UnitHeal.Location) >= 20f) && (!HasGlyph.Contains("55452") || (unit.Location.Distance(UnitHeal.Location) >= 40f)))
                {
                    return false;
                }
                return (HealWeight(unit) < THSettings.Instance.ChainHealHP);
            });
        }

        private static double CountUnitEarthquake(WoWUnit unitCenter)
        {
            return (double) FarFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(delegate (WoWUnit unit) {
                if ((!(Me.CurrentMap.Name == "Proving Grounds") && !IsDummy(unit)) && ((!unit.GotTarget || !FarFriendlyPlayers.Contains(unit.CurrentTarget)) || (unit.MaxHealth <= (MeMaxHealth * 0.5))))
                {
                    return false;
                }
                return (unitCenter.Location.Distance(unit.Location) <= 8f);
            });
        }

        private static double CountUnitHealingRain(WoWUnit unitCenter)
        {
            return (double) FarFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => ((unitCenter.Location.Distance(unit.Location) <= 10f) && (unit.HealthPercent <= THSettings.Instance.HealingRainHP)));
        }

        private static double CountUnitHealingRainNear(WoWUnit unitCenter)
        {
            return (double) FarFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => (unitCenter.Location.Distance(unit.Location) <= 10f));
        }

        private static double CountUnitHealingStreamTotem()
        {
            return (double) NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => ((unit.Combat && (unit.Distance <= 35.0)) && (HealWeight(unit) < THSettings.Instance.HealingStreamTotemHP)));
        }

        private static double CountUnitHealingTideTotem()
        {
            return (double) NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => (((unit.Combat && (unit.Distance <= 35.0)) && (HealWeight(unit) < THSettings.Instance.HealingTideTotemHP)) && !Invulnerable(unit)));
        }

        private static int CountUnitSpiritLink(WoWUnit unitCenter)
        {
            return NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => (unitCenter.Location.Distance(unit.Location) <= 10f));
        }

        private static double CountUnitThunderstorm()
        {
            return (double) FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(delegate (WoWUnit unit) {
                if ((!(Me.CurrentMap.Name == "Proving Grounds") && !IsDummy(unit)) && ((!unit.GotTarget || !FarFriendlyPlayers.Contains(unit.CurrentTarget)) || (unit.MaxHealth <= (MeMaxHealth * 0.5))))
                {
                    return false;
                }
                return (GetDistance(unit) <= 10f);
            });
        }

        private static double CountUnitThunderstormMelee()
        {
            return (double) NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Count<WoWUnit>(unit => ((((TalentSort(unit) < 2) && (GetDistance(unit) <= 10f)) && (!unit.IsStealthed && !DebuffCC(unit))) && !DebuffRoot(unit)));
        }

        internal static string CreateMD5Hash(string input)
        {
            byte[] bytes = Encoding.ASCII.GetBytes(input);
            return BitConverter.ToString(MD5.Create().ComputeHash(bytes)).Replace("-", "").ToLower();
        }

        private static bool CurrentTargetAttackable(double distance, bool includeCurrentTargetCheckInvulnerableePhysic = false, bool includeCurrentTargetCheckInvulnerableeMagic = false)
        {
            if (((Me.CurrentTarget == null) || !Me.CurrentTarget.IsValid) || (!Me.CurrentTarget.Attackable || !Me.CurrentTarget.IsAlive))
            {
                return false;
            }
            if (Me.CurrentTarget != CurrentTargetCheckLast)
            {
                CurrentTargetCheck();
            }
            return (((((CurrentTargetCheckIsEnemy && !CurrentTargetCheckDebuffCCBreakonDamage) && !CurrentTargetCheckInvulnerable) && ((CurrentTargetCheckFacing || THSettings.Instance.AutoFace) || !IsOverrideModeOn)) && (!includeCurrentTargetCheckInvulnerableePhysic || !CurrentTargetCheckInvulnerablePhysic)) && ((!includeCurrentTargetCheckInvulnerableeMagic || !CurrentTargetCheckInvulnerableMagic) && ((CurrentTargetCheckDist <= distance) && CurrentTargetCheckInLineOfSpellSight)));
        }

        private static bool CurrentTargetAttackableNoLoS(double distance)
        {
            if (((Me.CurrentTarget == null) || !Me.CurrentTarget.IsValid) || (!Me.CurrentTarget.Attackable || !Me.CurrentTarget.IsAlive))
            {
                return false;
            }
            if (Me.CurrentTarget != CurrentTargetCheckLast)
            {
                CurrentTargetCheck();
            }
            return ((!CurrentTargetCheckDebuffCCBreakonDamage && !CurrentTargetCheckInvulnerable) && (CurrentTargetCheckIsEnemy && (CurrentTargetCheckDist <= distance)));
        }

        private static void CurrentTargetCheck()
        {
            if (CurrentTargetCheckLastTime <= DateTime.Now)
            {
                CurrentTargetCheckLastTime = DateTime.Now + CurrentTargetCheckTimeOut;
                if (BasicCheck(Me.CurrentTarget))
                {
                    CurrentTargetCheckLast = Me.CurrentTarget;
                    CurrentTargetCheckFacing = Me.IsSafelyFacing(Me.CurrentTarget, 180f);
                    CurrentTargetCheckDist = GetDistance(Me.CurrentTarget);
                    CurrentTargetCheckIsEnemy = IsEnemy(Me.CurrentTarget);
                    if (CurrentTargetCheckIsEnemy)
                    {
                        CurrentTargetCheckInvulnerable = Invulnerable(Me.CurrentTarget);
                        if (!CurrentTargetCheckInvulnerable)
                        {
                            CurrentTargetCheckDebuffCCBreakonDamage = DebuffCCBreakonDamage(Me.CurrentTarget);
                            if (!CurrentTargetCheckDebuffCCBreakonDamage)
                            {
                                CurrentTargetCheckInvulnerableMagic = InvulnerableSpell(Me.CurrentTarget);
                                CurrentTargetCheckInvulnerablePhysic = InvulnerablePhysic(Me.CurrentTarget);
                                if (CurrentTargetCheckDist <= 5.0)
                                {
                                    CurrentTargetCheckInLineOfSpellSight = true;
                                }
                                else if (InLineOfSpellSightCheck(Me.CurrentTarget))
                                {
                                    CurrentTargetCheckInLineOfSpellSight = true;
                                }
                            }
                        }
                    }
                }
            }
        }

        private static Composite DeathRotation()
        {
            Composite[] children = new Composite[] { new Styx.TreeSharp.Action(delegate (object r) {
                Styx.Common.Logging.Write("Waiting up to {0} seconds for clear area to use {1}...", new object[] { 10, SelfRezSpell });
            }), new Wait(10, delegate (object until) {
                MobsNearby = CountEnemyNear(Me, 20f);
                if ((MobsNearby > 0.0) && !Me.IsAlive)
                {
                    return Me.IsGhost;
                }
                return true;
            }, new Styx.TreeSharp.Action(delegate (object r) {
                if (Me.IsGhost)
                {
                    Styx.Common.Logging.Write("Insignia taken or corpse release by something other than Singular...");
                    return RunStatus.Failure;
                }
                if (Me.IsAlive)
                {
                    Styx.Common.Logging.Write("Ressurected by something other than Singular...");
                    return RunStatus.Failure;
                }
                return RunStatus.Success;
            })), new DecoratorContinue(req => MobsNearby > 0.0, new Styx.TreeSharp.Action(delegate (object r) {
                Styx.Common.Logging.Write("Still {0} enemies within {1} yds, skipping {2}", new object[] { MobsNearby, 20, SelfRezSpell });
                return RunStatus.Failure;
            })), new Styx.TreeSharp.Action(delegate (object r) {
                Styx.Common.Logging.Write("Ressurrecting Singular by invoking {0}...", new object[] { SelfRezSpell });
            }), new Styx.TreeSharp.Action(delegate (object r) {
                Lua.DoString("UseSoulstone()", "WoW.lua");
            }), new WaitContinue(1, delegate (object until) {
                if (!Me.IsAlive)
                {
                    return Me.IsGhost;
                }
                return true;
            }, new ActionAlwaysSucceed()) };
            return new Decorator(delegate (object req) {
                if (Me.IsAlive || Me.IsGhost)
                {
                    return false;
                }
                List<string> returnValues = Lua.GetReturnValues("return HasSoulstone()", "hawker.lua");
                if (((returnValues == null) || (returnValues.Count == 0)) || (string.IsNullOrEmpty(returnValues[0]) || (returnValues[0].ToLower() == "nil")))
                {
                    return false;
                }
                if (!THSettings.Instance.AutoMove)
                {
                    if (NextSuppressMessage < DateTime.Now)
                    {
                        NextSuppressMessage = DateTime.Now.AddSeconds(10.0);
                        Styx.Common.Logging.Write("Suppressing {0} behavior since movement disabled...", new object[] { returnValues[0] });
                    }
                    return false;
                }
                SelfRezSpell = returnValues[0];
                return true;
            }, new Sequence(children));
        }

        private Composite DeathSelector()
        {
            if (this._deathBehavior == null)
            {
                Styx.Common.Logging.Write("Initializing death behaviours.");
                this._deathBehavior = new PrioritySelector(new Composite[] { DeathRotation() });
            }
            return null;
        }

        private static bool Debuff63280Duration(WoWUnit target, double duration, bool LogSpell = false)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => Debuff63280DurationHS.Contains(aura.SpellId));
        }

        private static bool DebuffCC(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => DebuffCCHS.Contains(aura.SpellId));
        }

        private static bool DebuffCCBreakonDamage(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => DebuffCCBreakonDamageHS.Contains(aura.SpellId));
        }

        private static bool DebuffCCDuration(WoWUnit target, double duration, bool LogSpell = false)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => (DebuffCCDurationHS.Contains(aura.SpellId) && (aura.TimeLeft.TotalMilliseconds >= duration)));
        }

        private static bool DebuffCCleanseASAP(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid || (Me.CurrentMap.Name == "Proving Grounds"))
            {
                return target.GetAllAuras().Any<WoWAura>(aura => DebuffCCleanseASAPPvEHS.Contains(aura.SpellId));
            }
            if ((target.IsPlayer && (target.Class == WoWClass.Warrior)) && target.GetAllAuras().Any<WoWAura>(aura => DebuffCCleanseASAPHSWarrior.Contains(aura.SpellId)))
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => (DebuffCCleanseASAPPvPHS.Contains(aura.SpellId) && (aura.TimeLeft.TotalMilliseconds > 3000.0)));
        }

        private static bool DebuffDisarm(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return (target.Disarmed || target.GetAllAuras().Any<WoWAura>(aura => DebuffDisarmHS.Contains(aura.SpellId)));
        }

        private static bool DebuffDoNotCleanse(WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => DebuffDoNotCleanseHS.Contains(aura.SpellId));
        }

        private static bool DebuffDoNotHeal(WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => DebuffDoNotHealHS.Contains(aura.SpellId));
        }

        private static bool DebuffDot(WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!aura.IsHarmful)
                {
                    return false;
                }
                if (aura.ApplyAuraType != WoWApplyAuraType.PeriodicDamage)
                {
                    return (aura.ApplyAuraType == WoWApplyAuraType.PeriodicDamagePercent);
                }
                return true;
            });
        }

        private static double DebuffDotCount(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return 0.0;
            }
            return (double) target.GetAllAuras().Count<WoWAura>(aura => (aura.IsHarmful && (aura.ApplyAuraType == WoWApplyAuraType.PeriodicDamage)));
        }

        private static bool DebuffDotDuration(WoWUnit target, int duration)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => ((aura.IsHarmful && (aura.ApplyAuraType == WoWApplyAuraType.PeriodicDamage)) && (aura.TimeLeft.TotalMilliseconds >= duration)));
        }

        private static bool DebuffFearDuration(WoWUnit target, double duration)
        {
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if ((!DebuffFearDurationHS.Contains(aura.SpellId) && (aura.ApplyAuraType != WoWApplyAuraType.ModFear)) && (aura.ApplyAuraType != WoWApplyAuraType.ModCharm))
                {
                    return false;
                }
                return (aura.TimeLeft.TotalMilliseconds > duration);
            });
        }

        private static bool DebuffMagicCCDuration(WoWUnit target, double duration)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => (DebuffMagicCCDurationHS.Contains(aura.SpellId) && (aura.TimeLeft.TotalMilliseconds >= duration)));
        }

        private static bool DebuffRoot(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffRootHS.Contains(aura.SpellId))
                {
                    return (aura.ApplyAuraType == WoWApplyAuraType.ModRoot);
                }
                return true;
            });
        }

        private static bool DebuffRootCanCleanse(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffRootCanCleanseHS.Contains(aura.SpellId))
                {
                    if (aura.ApplyAuraType != WoWApplyAuraType.ModRoot)
                    {
                        return false;
                    }
                    if (aura.Spell.DispelType != WoWDispelType.Magic)
                    {
                        return (aura.Spell.DispelType == WoWDispelType.Poison);
                    }
                }
                return true;
            });
        }

        private static bool DebuffRootCanCloak(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => DebuffRootCanCloakHS.Contains(aura.SpellId));
        }

        private static bool DebuffRootDuration(WoWUnit target, int duration)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            if (UnitHasAura("Hand of Freedom", target))
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffRootHS.Contains(aura.SpellId) && (aura.ApplyAuraType != WoWApplyAuraType.ModRoot))
                {
                    return false;
                }
                return (aura.TimeLeft.TotalMilliseconds > duration);
            });
        }

        private static bool DebuffRootorSnare(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            if (UnitHasAura("Hand of Freedom", target))
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffRootorSnareHS.Contains(aura.SpellId) && (aura.ApplyAuraType != WoWApplyAuraType.ModRoot))
                {
                    return (aura.ApplyAuraType == WoWApplyAuraType.ModDecreaseSpeed);
                }
                return true;
            });
        }

        private static int DebuffRootorSnareCount(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return 0;
            }
            return target.GetAllAuras().Count<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffRootorSnareHS.Contains(aura.SpellId) && (aura.ApplyAuraType != WoWApplyAuraType.ModRoot))
                {
                    return (aura.ApplyAuraType == WoWApplyAuraType.ModDecreaseSpeed);
                }
                return true;
            });
        }

        private static bool DebuffSilence(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffSilenceHS.Contains(aura.SpellId))
                {
                    return (aura.ApplyAuraType == WoWApplyAuraType.ModSilence);
                }
                return true;
            });
        }

        private static bool DebuffSnare(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            if (UnitHasAura("Hand of Freedom", target))
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffSnareHS.Contains(aura.SpellId))
                {
                    return (aura.ApplyAuraType == WoWApplyAuraType.ModDecreaseSpeed);
                }
                return true;
            });
        }

        private static bool DebuffStun(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffStunDurationHS.Contains(aura.SpellId))
                {
                    return (aura.ApplyAuraType == WoWApplyAuraType.ModStun);
                }
                return true;
            });
        }

        private static bool DebuffStunDuration(WoWUnit target, double duration)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffStunDurationHS.Contains(aura.SpellId) && (aura.ApplyAuraType != WoWApplyAuraType.ModStun))
                {
                    return false;
                }
                return (aura.TimeLeft.TotalMilliseconds >= duration);
            });
        }

        private static double DebuffStunDurationTimeLeft(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return 0.0;
            }
            WoWAura aura = (from aura in target.GetAllAuras()
                orderby aura.TimeLeft descending
                select aura).FirstOrDefault<WoWAura>(delegate (WoWAura aura) {
                if (!DebuffStunDurationHS.Contains(aura.SpellId))
                {
                    return aura.ApplyAuraType == WoWApplyAuraType.ModStun;
                }
                return true;
            });
            if (aura == null)
            {
                return 0.0;
            }
            return aura.TimeLeft.TotalMilliseconds;
        }

        private static bool DebuffStunFearDuration(WoWUnit target, double duration)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if ((!DebuffStunFearDurationHS.Contains(aura.SpellId) && (aura.ApplyAuraType != WoWApplyAuraType.ModStun)) && (aura.ApplyAuraType != WoWApplyAuraType.ModFear))
                {
                    return false;
                }
                return (aura.TimeLeft.TotalMilliseconds >= duration);
            });
        }

        internal static string Decrypt(string cipherText, string passPhrase)
        {
            byte[] bytes = Encoding.ASCII.GetBytes("www.tuanha.biz/l");
            byte[] buffer = Convert.FromBase64String(cipherText);
            byte[] rgbKey = new PasswordDeriveBytes(passPhrase, null).GetBytes(0x20);
            ICryptoTransform transform = new RijndaelManaged { Mode = CipherMode.CBC }.CreateDecryptor(rgbKey, bytes);
            MemoryStream stream = new MemoryStream(buffer);
            CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Read);
            byte[] buffer4 = new byte[buffer.Length];
            int count = stream2.Read(buffer4, 0, buffer4.Length);
            stream.Close();
            stream2.Close();
            return Encoding.UTF8.GetString(buffer4, 0, count);
        }

        private static void DetachCombatLogEventPvP()
        {
            if (CombatLogAttachedPvP)
            {
                Styx.Common.Logging.Write("DetachCombatLogEventPvP");
                Styx.Common.Logging.Write("Removed combat log filter");
                Lua.Events.RemoveFilter("COMBAT_LOG_EVENT_UNFILTERED");
                Styx.Common.Logging.Write("Detached combat log");
                Lua.Events.DetachEvent("COMBAT_LOG_EVENT_UNFILTERED", new LuaEventHandlerDelegate(Classname.HandleCombatLogPvP));
                CombatLogAttachedPvP = false;
            }
        }

        private static Composite Dismount()
        {
            return new Decorator(ret => ((IsUsingAFKBot && (Me.Combat || Me.CurrentMap.IsBattleground)) && ((Me.Mounted && !Me.IsFlying) && !IsMoving(Me))) && HasEnemyNear(Me, 30f), new Styx.TreeSharp.Action(delegate (object param0) {
                Mount.Dismount("Stuck on mount? Dismounting for combat.");
                return RunStatus.Failure;
            }));
        }

        private static void DumpAuras()
        {
            if (_lastGetAllMyAuras.AddSeconds(10.0) < DateTime.Now)
            {
                int num = 1;
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "----------------------------------");
                foreach (WoWAura aura in Me.GetAllAuras())
                {
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, string.Concat(new object[] { num, ". Me.GetAllAuras Name: ", aura.Name, " - SpellId: ", aura.SpellId }));
                    num++;
                }
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "----------------------------------");
                num = 1;
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "----------------------------------");
                foreach (KeyValuePair<string, WoWAura> pair in Me.Auras)
                {
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, string.Concat(new object[] { num, ". Me.Auras - Name: ", pair.Value.Name, " - SpellId: ", pair.Value.SpellId }));
                    num++;
                }
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "----------------------------------");
                num = 1;
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "----------------------------------");
                foreach (WoWAura aura2 in Me.GetAllAuras())
                {
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, string.Concat(new object[] { num, ". Me.GetAllAuras() - Name: ", aura2.Name, " - SpellId: ", aura2.SpellId }));
                    num++;
                }
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "----------------------------------");
                num = 1;
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "----------------------------------");
                foreach (KeyValuePair<string, WoWAura> pair2 in Me.PassiveAuras)
                {
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, string.Concat(new object[] { num, ". Me.PassiveAuras - Name: ", pair2.Value.Name, " - SpellId: ", pair2.Value.SpellId }));
                    num++;
                }
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "----------------------------------");
                _lastGetAllMyAuras = DateTime.Now;
            }
        }

        private static Composite Earthbind()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => ((THSettings.Instance.Earthbind && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && (((Me.HealthPercent > THSettings.Instance.PriorityHeal) && !MyTotemEarthCheck(Me, 40)) && CanCastCheck("Earthgrab Totem", false))) && (CountNearEnemyEarthbindNoRooted(Me, THSettings.Instance.EarthbindDistance) >= THSettings.Instance.EarthbindUnit), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Earthgrab Totem", Me, "Earthgrab");
            })), new Decorator(ret => ((THSettings.Instance.Earthbind && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && (((Me.HealthPercent > THSettings.Instance.PriorityHeal) && !SpellManager.HasSpell("Earthgrab Totem")) && (!MyTotemEarthCheck(Me, 40) && CanCastCheck("Earthbind Totem", false)))) && (CountNearEnemyEarthbind(Me, THSettings.Instance.EarthbindDistance) >= THSettings.Instance.EarthbindUnit), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Earthbind Totem", Me, "Earthbind");
            })) });
        }

        private static Composite EarthElemental()
        {
            return new Decorator(ret => (((THSettings.Instance.EarthElementalCooldown || (THSettings.Instance.EarthElementalBurst && THSettings.Instance.Burst)) && ((CurrentTargetAttackable(30.0, false, false) && !CurrentTargetCheckInvulnerablePhysic) && (IsWorthyTarget(Me.CurrentTarget, 2.0, 0.5) || HaveWorthyTargetAttackingMe()))) && !HasElementalAround()) && CanCastCheck("Earth Elemental Totem", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Earth Elemental Totem", Me.CurrentTarget, "EarthElemental");
            }));
        }

        private static Composite Earthquake()
        {
            return new Decorator(ret => ((THSettings.Instance.Earthquake && (Me.ManaPercent >= THSettings.Instance.EleAoEMana)) && CanCastCheck("Earthquake", false)) && GetUnitEarthquake(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Earthquake", UnitEarthquake, "Earthquake");
                ObjectManager.Update();
                SpellManager.ClickRemoteLocation(UnitEarthquake.Location);
            }));
        }

        private static Composite EarthShield()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.EarthShield && (LastEarthShield < DateTime.Now)) && ((Me.CurrentMap.IsDungeon || Me.CurrentMap.IsRaid) || (Me.CurrentMap.Name == "Proving Grounds"))) && (CanCastCheck("Earth Shield", false) && GetUnitTankToEarthShield())) && (!GetUnitTankHasMyEarthShield() || (GetUnitTankHasMyEarthShield() && ((HealWeight(UnitTankHasMyEarthShield) - 20.0) > HealWeight(UnitTankToEarthShield)))), new Styx.TreeSharp.Action(delegate (object param0) {
                LastEarthShield = DateTime.Now + TimeSpan.FromMilliseconds(3000.0);
                CastSpell("Earth Shield", UnitTankToEarthShield, "EarthShieldTank");
            })), new Decorator(ret => (((THSettings.Instance.EarthShieldAlways && (Me.ManaPercent > THSettings.Instance.WaterShieldAlwaysMana)) && ((Me.HealthPercent <= THSettings.Instance.EarthShieldAlwaysHP) && !MeHasAura("Earth Shield"))) && CanCastCheck("Earth Shield", false)) && HaveDPSTarget(Me), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Earth Shield", Me, "EarthShieldAlways");
            })), new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.EarthShield || Me.CurrentMap.IsDungeon) || (Me.CurrentMap.IsRaid || !(Me.CurrentMap.Name != "Proving Grounds"))) || (!CanCastCheck("Earth Shield", false) || !GetUnitEarthShield()))
                {
                    return false;
                }
                return !GetUnitHasMyEarthShield() || (GetUnitHasMyEarthShield() && ((HealWeight(UnitHasMyEarthShield) - 15.0) > HealWeight(UnitEarthShield)));
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Earth Shield", UnitEarthShield, "EarthShield Swith Earth Shield Unit");
            })) });
        }

        private static Composite EarthShock()
        {
            return new Decorator(ret => ((THSettings.Instance.EarthShock && CurrentTargetAttackable((double) ((int) SpellManager.Spells["Earth Shock"].MaxRange), false, false)) && !CurrentTargetCheckInvulnerableMagic) && CanCastCheck("Earth Shock", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Earth Shock", Me.CurrentTarget, "EarthShock");
            }));
        }

        private static Composite EarthShockElemental()
        {
            return new Decorator(ret => (((THSettings.Instance.EarthShockElemental && CurrentTargetAttackable((double) ((int) SpellManager.Spells["Earth Shock"].MaxRange), false, false)) && (!CurrentTargetCheckInvulnerableMagic && !MeHasAura(0x12fc2))) && (MyAuraStackCount("Lightning Shield", Me) >= THSettings.Instance.EarthShockElementalCharge)) && CanCastCheck("Earth Shock", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Earth Shock", Me.CurrentTarget, "EarthShockElemental");
            }));
        }

        private static Composite EarthShockElementalPvP()
        {
            return new Decorator(ret => ((THSettings.Instance.EarthShockElemental && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && ((CurrentTargetAttackable((double) ((int) SpellManager.Spells["Earth Shock"].MaxRange), false, false) && !CurrentTargetCheckInvulnerableMagic) && (!MeHasAura(0x12fc2) && CanCastCheck("Earth Shock", false)))) && (MyAuraStackCount("Lightning Shield", Me) >= THSettings.Instance.EarthShockElementalCharge), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Earth Shock", Me.CurrentTarget, "EarthShockElemental");
            }));
        }

        private static Composite ElementalBlastEle()
        {
            return new Decorator(ret => (((THSettings.Instance.ElementalBlastEle && CurrentTargetAttackable(40.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget))) && !MeHasAura(0x12fc2)) && CanCastCheck("Elemental Blast", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Elemental Blast", Me.CurrentTarget, "ElementalBlastEle");
            }));
        }

        private static Composite ElementalBlastEnh()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.ElementalBlastEle || !CurrentTargetAttackable(40.0, false, false)) || (CurrentTargetCheckInvulnerableMagic || !FacingOverride(Me.CurrentTarget))) || ((MyAuraStackCount(0xd239, Me) < THSettings.Instance.ElementalBlastEnhStack) && (CurrentTargetAttackable(5.0, false, false) || !DebuffRoot(Me))))
                {
                    return false;
                }
                return CanCastCheck("Elemental Blast", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Elemental Blast", Me.CurrentTarget, "ElementalBlastEnh");
            }));
        }

        private static Composite ElementalMastery()
        {
            return new Decorator(ret => ((THSettings.Instance.ElementalMasteryCooldown || (THSettings.Instance.ElementalMasteryBurst && THSettings.Instance.Burst)) && Me.Combat) && CanCastCheck("Elemental Mastery", true), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Elemental Mastery", Me, "ElementalMastery");
                return RunStatus.Failure;
            }));
        }

        private static Composite ElementalRotation()
        {
            return new PrioritySelector(new Composite[] { new Styx.TreeSharp.Action(delegate (object param0) {
                if (LastAoESearch <= DateTime.Now)
                {
                    if ((THSettings.Instance.AutoAoE && (LastAoESearch < DateTime.Now)) && (CurrentTargetAttackable(40.0, false, false) && (CountEnemyNear(Me.CurrentTarget, 15f) >= THSettings.Instance.UnittoStartAoE)))
                    {
                        AoEModeOn = true;
                    }
                    else
                    {
                        AoEModeOn = false;
                    }
                    LastAoESearch = DateTime.Now + TimeSpan.FromMilliseconds(3000.0);
                }
                return RunStatus.Failure;
            }), AutoTargetRange(), MovementMoveStop(ret => Me.CurrentTarget, 20.0), MovementMoveToLoS(ret => Me.CurrentTarget), TargetMyPetTarget(), GhostWolfHoldComp(), new Decorator(ret => !AoEModeOn && !Me.Mounted, new PrioritySelector(new Composite[] { 
                ShamanisticRage(), AscendanceEle(), ElementalMastery(), AncestralGuidance(), Windwalk(), Stormlash(), Hex(), StoneBulwarkTotem(), AstralShift(), GroundingLow(), Capacitor(), ThunderstormCast(), CleanseSpiritFriendlyASAPEle(), ThunderstormMelee(), HealingTideTotem(), LightningShield(), 
                FlameShockEle(), LavaBustElementalProc(), SearingTotem(), FlameShockRogueDruid(), FireElemental(), EarthElemental(), HealingStreamTotem(), Thunderstorm(), ThunderstormMana(), FrostShockNearby(), UnleashElementsEle(), EarthShockElementalPvP(), Earthbind(), LavaBustElemental(), ElementalBlastEle(), PurgeASAPEleEnh(), 
                EarthShockElemental(), BindElemental(), FlameShockAoEEle(), HealingSurgeInCombatEle(), ChainLightningEle(), LightningBoltFillerElemental(), CleanseSpiritFriendlyEle(), HealingSurgeOutCombatEle(), WaterWalking(), GhostWolfEle(), TemporaryEnchantment(), AutoRez()
             })), new Decorator(ret => AoEModeOn && !Me.Mounted, new PrioritySelector(new Composite[] { 
                ShamanisticRage(), AscendanceEle(), ElementalMastery(), AncestralGuidance(), Windwalk(), Stormlash(), StoneBulwarkTotem(), AstralShift(), GroundingLow(), Capacitor(), ThunderstormCast(), CleanseSpiritFriendlyASAPEle(), ThunderstormMelee(), EarthElemental(), FireElemental(), HealingTideTotem(), 
                HealingStreamTotem(), MagmaTotemEle(), Earthquake(), Thunderstorm(), ThunderstormMana(), LavaBustElementalProc(), SearingTotem(), FlameShockEle(), EarthShockElemental(), FlameShockAoEEle(), Earthbind(), ElementalBlastEle(), ChainLightningEleAoE(), HealingSurgeInCombatEle(), BindElemental(), LightningBoltFillerElementalAoE(), 
                Hex(), CleanseSpiritFriendlyEle(), HealingSurgeOutCombatEle()
             })), WriteDebug("") });
        }

        internal static string Encrypt(string plainText, string passPhrase)
        {
            byte[] bytes = Encoding.UTF8.GetBytes("www.tuanha.biz/l");
            byte[] buffer = Encoding.UTF8.GetBytes(plainText);
            byte[] rgbKey = new PasswordDeriveBytes(passPhrase, null).GetBytes(0x20);
            ICryptoTransform transform = new RijndaelManaged { Mode = CipherMode.CBC }.CreateEncryptor(rgbKey, bytes);
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write);
            stream2.Write(buffer, 0, buffer.Length);
            stream2.FlushFinalBlock();
            byte[] inArray = stream.ToArray();
            stream.Close();
            stream2.Close();
            return Convert.ToBase64String(inArray);
        }

        private static void EnemyListCacheAdd(WoWUnit unit, int expireSeconds = 10)
        {
            if ((!MeHasAura("Arena Preparation") && !MeHasAura("Preparation")) && !EnemyListCache.ContainsKey(unit.Guid))
            {
                EnemyListCache.Add(unit.Guid, DateTime.Now + TimeSpan.FromSeconds((double) expireSeconds));
            }
        }

        private static void EnemyListCacheClear()
        {
            if (EnemyListCacheClearLast <= DateTime.Now)
            {
                EnemyListCacheClearLast = DateTime.Now + TimeSpan.FromSeconds(5.0);
                foreach (ulong num in (from unit in EnemyListCache
                    where unit.Value < DateTime.Now
                    select unit.Key).ToList<ulong>())
                {
                    EnemyListCache.Remove(num);
                }
            }
        }

        private static Composite EnhancementRotation()
        {
            return new PrioritySelector(new Composite[] { new Styx.TreeSharp.Action(delegate (object param0) {
                if (LastAoESearch <= DateTime.Now)
                {
                    if (THSettings.Instance.AutoAoE && (CountEnemyNear(Me, 10f) >= THSettings.Instance.UnittoStartAoE))
                    {
                        AoEModeOn = true;
                    }
                    else
                    {
                        AoEModeOn = false;
                    }
                    LastAoESearch = DateTime.Now + TimeSpan.FromMilliseconds(3000.0);
                }
                return RunStatus.Failure;
            }), AutoTargetMelee(), MovementMoveToMelee(ret => Me.CurrentTarget), MovementMoveStop(ret => Me.CurrentTarget, 3.0), TargetMyPetTarget(), GhostWolfHoldComp(), new Decorator(ret => !AoEModeOn && !Me.Mounted, new PrioritySelector(new Composite[] { 
                AutoAttack(), AutoAttackOffTarget(), ShamanisticRage(), AscendanceEnh(), ElementalMastery(), AncestralGuidance(), Windwalk(), Stormblast(), Hex(), Stormlash(), StoneBulwarkTotem(), AstralShift(), GroundingLow(), Capacitor(), CleanseSpiritFriendlyASAPEnh(), EarthElemental(), 
                FireElemental(), HealingTideTotem(), HealingStreamTotem(), HealingSurgeInCombatEnh(), LightningShield(), FeralSpirit(), FireElemental(), EarthElemental(), FlameShockRogueDruid(), FrostShockEnhRoot(), FlameShockEnhNoFlametongue(), UnleashElementsEnhSnare(), FrostShockEnh(), SearingTotem(), ElementalBlastEnh(), UnleashElementsEnhUnleashedFury(), 
                LightningBoltEnh(), LightningBoltAncestralSwiftness(), Stormstrike(), FlameShockUnleashFlame(), BindElemental(), LavaLash(), UnleashElementsEnh(), PurgeASAPEleEnh(), EarthShock(), Earthbind(), LightningBoltFillerEnh(), LightningBoltFillerEnhRange(), FireNovaLoS(), CleanseSpiritFriendlyEnh(), HealingSurgeOutCombatEnh(), WaterWalking(), 
                GhostWolfEnh(), TemporaryEnchantment(), AutoRez()
             })), new Decorator(ret => AoEModeOn && !Me.Mounted, new PrioritySelector(new Composite[] { 
                AutoAttack(), ShamanisticRage(), AscendanceEnh(), ElementalMastery(), AncestralGuidance(), Windwalk(), Stormblast(), Stormlash(), StoneBulwarkTotem(), AstralShift(), GroundingLow(), Capacitor(), CleanseSpiritFriendlyASAPEnh(), HealingTideTotem(), HealingStreamTotem(), HealingSurgeInCombatEnh(), 
                FeralSpirit(), FireElemental(), EarthElemental(), MagmaTotemEnh(), FireNovaAoE(), FlameShockEnh(), BindElemental(), LavaLash(), UnleashElementsEnhUnleashedFury(), ChainLightning5MW(), Stormstrike(), ElementalBlastEnh(), Hex(), Earthbind(), CleanseSpiritFriendlyEnh(), HealingSurgeOutCombatEnh()
             })) });
        }

        private static bool Eval(string Name, Func<bool> func)
        {
            sw.Reset();
            sw.Start();
            bool flag = func();
            sw.Stop();
            Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "{0} ms - {1} , result is {2}", new object[] { Math.Round(sw.Elapsed.TotalMilliseconds, 5), Name, flag });
            return flag;
        }

        private static int Eval(string Name, Func<int> func)
        {
            sw.Reset();
            sw.Start();
            int num = func();
            sw.Stop();
            Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "{0} ms - {1} , result is {2}", new object[] { Math.Round(sw.Elapsed.TotalMilliseconds, 5), Name, num });
            return num;
        }

        private static bool FacingOverride(WoWUnit unit)
        {
            if (!BasicCheck(unit))
            {
                return false;
            }
            if ((!Me.IsSafelyFacing(unit, 180f) && (!Me.IsMoving || !Me.IsSafelyFacing(unit, 220f))) && (!THSettings.Instance.AutoFace || IsOverrideModeOn))
            {
                return false;
            }
            return true;
        }

        private static Composite FeralSpirit()
        {
            return new PrioritySelector(new Composite[] { new Decorator(delegate (object ret) {
                if ((THSettings.Instance.FeralSpiritCooldown || (THSettings.Instance.FeralSpiritBurst && THSettings.Instance.Burst)) && ((CurrentTargetAttackable(30.0, false, false) && !CurrentTargetCheckInvulnerablePhysic) && CanCastCheck("Feral Spirit", false)))
                {
                    if (!IsWorthyTarget(Me.CurrentTarget, 2.0, 0.5))
                    {
                        return HaveWorthyTargetAttackingMe();
                    }
                    return true;
                }
                return false;
            }, new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Feral Spirit", Me.CurrentTarget, "FeralSpirit");
            })), new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.FeralSpiritLow || (Me.HealthPercent > THSettings.Instance.FeralSpiritLowHP)) || (!CurrentTargetAttackable(30.0, false, false) || CurrentTargetCheckInvulnerablePhysic)) || !CanCastCheck("Feral Spirit", false))
                {
                    return false;
                }
                if (!IsWorthyTarget(Me.CurrentTarget, 2.0, 0.5))
                {
                    return HaveWorthyTargetAttackingMe();
                }
                return true;
            }, new Styx.TreeSharp.Action(delegate (object ret) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Feral Spirit", Me.CurrentTarget, "FeralSpiritLow");
            })) });
        }

        private static WoWPoint FindGround(WoWPoint Point, int HoverZ)
        {
            if (!Me.CurrentMap.IsArena || !Me.CurrentMap.IsBattleground)
            {
                return Point;
            }
            WoWPoint point = new WoWPoint(Point.X, Point.Y, Point.Z + HoverZ);
            return new WoWPoint(Point.X, Point.Y, point.Z - HeightOffTheGround(point, HoverZ));
        }

        private static Composite FireElemental()
        {
            return new Decorator(ret => ((THSettings.Instance.FireElementalCooldown || (THSettings.Instance.FireElementalBurst && THSettings.Instance.Burst)) && (((CurrentTargetAttackable(30.0, false, false) && !CurrentTargetCheckInvulnerablePhysic) && CanCastCheck("Fire Elemental Totem", false)) && (IsWorthyTarget(Me.CurrentTarget, 2.0, 0.5) || HaveWorthyTargetAttackingMe()))) && !HasElementalAround(), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Fire Elemental Totem", Me.CurrentTarget, "FireElemental");
            }));
        }

        private static Composite FireNovaAoE()
        {
            return new Decorator(ret => ((THSettings.Instance.FireNova && (Me.ManaPercent > 20.0)) && CanCastCheck("Fire Nova", false)) && HasEnemyFlameShock(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Fire Nova", Me, "FireNovaAoE");
            }));
        }

        private static Composite FireNovaLoS()
        {
            return new Decorator(ret => ((THSettings.Instance.FireNova && !CurrentTargetAttackable(30.0, false, false)) && ((Me.ManaPercent > 20.0) && CanCastCheck("Fire Nova", false))) && HasEnemyFlameShock(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Fire Nova", Me, "FireNovaLoS");
            }));
        }

        private static Composite FlameShock55447()
        {
            return new Decorator(ret => ((THSettings.Instance.FlameShockEnh && (HealWeightUnitHeal > THSettings.Instance.PriorityHeal)) && (HasGlyph.Contains("55447") && CanCastCheck("Flame Shock", false))) && GetUnitFlameShock55447(), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(UnitFlameShock55447);
                CastSpell("Flame Shock", UnitFlameShock55447, "FlameShock55447");
            }));
        }

        private static Composite FlameShockAoEEle()
        {
            return new Decorator(ret => ((THSettings.Instance.FlameShockEle && (Me.ManaPercent >= (THSettings.Instance.EleAoEMana - 10))) && (ShouldFlameShockAoE() && CanCastCheck("Flame Shock", false))) && GetUnitFlameShockAoE(), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(UnitFlameShockAoE);
                CastSpell("Flame Shock", UnitFlameShockAoE, "FlameShockAoEEle");
            }));
        }

        private static Composite FlameShockEle()
        {
            return new Decorator(ret => ((THSettings.Instance.FlameShockEle && CurrentTargetAttackable((double) ((int) SpellManager.Spells["Flame Shock"].MaxRange), false, false)) && (!CurrentTargetCheckInvulnerableMagic && (MyAuraTimeLeft("Flame Shock", Me.CurrentTarget) < 5000.0))) && CanCastCheck("Flame Shock", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Flame Shock", Me.CurrentTarget, "FlameShockEle");
            }));
        }

        private static Composite FlameShockEnh()
        {
            return new Decorator(ret => ((THSettings.Instance.FlameShockEnh && CurrentTargetAttackable((double) ((int) SpellManager.Spells["Flame Shock"].MaxRange), false, false)) && (!CurrentTargetCheckInvulnerableMagic && (MyAuraTimeLeft("Flame Shock", Me.CurrentTarget) < 5000.0))) && CanCastCheck("Flame Shock", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Flame Shock", Me.CurrentTarget, "FlameShockEnh");
            }));
        }

        private static Composite FlameShockEnhNoFlametongue()
        {
            return new Decorator(ret => ((((THSettings.Instance.FlameShockEnh && CurrentTargetAttackable((double) ((int) SpellManager.Spells["Flame Shock"].MaxRange), false, false)) && !CurrentTargetCheckInvulnerableMagic) && ((Me.Inventory.Equipped.OffHand == null) || ((Me.Inventory.Equipped.OffHand != null) && (Me.Inventory.Equipped.OffHand.TemporaryEnchantment.Id != 5)))) && (MyAuraTimeLeft("Flame Shock", Me.CurrentTarget) < 3000.0)) && CanCastCheck("Flame Shock", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Flame Shock", Me.CurrentTarget, "FlameShockEnhNoFlametongue");
            }));
        }

        private static Composite FlameShockRogueDruid()
        {
            return new Decorator(ret => (((THSettings.Instance.FlameShockRogueDruid && (HealWeightUnitHeal > THSettings.Instance.UrgentHeal)) && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && CanCastCheck("Flame Shock", false)) && GetUnitFlameShockRogueDruid(), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(UnitFlameShockRogueDruid);
                CastSpell("Flame Shock", UnitFlameShockRogueDruid, "FlameShockRogueDruid");
            }));
        }

        private static Composite FlameShockUnleashFlame()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.FlameShockEnh || !CurrentTargetAttackable((double) ((int) SpellManager.Spells["Flame Shock"].MaxRange), false, false)) || (CurrentTargetCheckInvulnerableMagic || !IsWorthyTarget(Me.CurrentTarget, 1.0, 0.3))) || ((!MyAura("Unleash Flame", Me) && MyAura("Flame Shock", Me.CurrentTarget)) && ((MyAuraTimeLeft("Flame Shock", Me.CurrentTarget) >= 3000.0) || (SpellManager.HasSpell("Unleash Elements") && (!SpellManager.HasSpell("Unleash Elements") || (SpellManager.Spells["Unleash Elements"].CooldownTimeLeft.TotalMilliseconds <= 5000.0))))))
                {
                    return false;
                }
                return CanCastCheck("Flame Shock", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Flame Shock", Me.CurrentTarget, "FlameShockUnleashFlame");
            }));
        }

        private static void FriendListCacheAdd(WoWUnit unit, int expireSeconds = 60)
        {
            if (!FriendListCache.ContainsKey(unit.Guid))
            {
                FriendListCache.Add(unit.Guid, DateTime.Now + TimeSpan.FromSeconds((double) expireSeconds));
            }
        }

        private static void FriendListCacheClear()
        {
            if (FriendListCacheClearLast <= DateTime.Now)
            {
                FriendListCacheClearLast = DateTime.Now + TimeSpan.FromSeconds(5.0);
                foreach (ulong num in (from unit in FriendListCache
                    where unit.Value < DateTime.Now
                    select unit.Key).ToList<ulong>())
                {
                    FriendListCache.Remove(num);
                }
            }
        }

        private static Composite FrostShockEnh()
        {
            return new Decorator(ret => (((THSettings.Instance.FrostShockEnh && CurrentTargetAttackable((double) ((int) SpellManager.Spells["Frost Shock"].MaxRange), false, false)) && (!CurrentTargetCheckInvulnerableMagic && (CurrentTargetCheckDist >= THSettings.Instance.FrostShockEnhMinDistance))) && (!DebuffSnare(Me.CurrentTarget) && !InvulnerableRootandSnare(Me.CurrentTarget))) && CanCastCheck("Frost Shock", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Frost Shock", Me.CurrentTarget, "FrostShockEnh");
            }));
        }

        private static Composite FrostShockEnhRoot()
        {
            return new Decorator(ret => (((THSettings.Instance.FrostShockEnh && CurrentTargetAttackable((double) ((int) SpellManager.Spells["Frost Shock"].MaxRange), false, false)) && (!CurrentTargetCheckInvulnerableMagic && (CurrentTargetCheckDist >= THSettings.Instance.FrostShockEnhMinDistance))) && (!DebuffRoot(Me.CurrentTarget) && !InvulnerableRootandSnare(Me.CurrentTarget))) && CanCastCheck("Frost Shock", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Frost Shock", Me.CurrentTarget, "FrostShockEnhRoot");
            }));
        }

        private static Composite FrostShockNearby()
        {
            return new Decorator(ret => (((THSettings.Instance.FrostShockNearby && (HealWeightUnitHeal > THSettings.Instance.PriorityHeal)) && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && ((Me.ManaPercent >= THSettings.Instance.FrostShockNearbyMana) && CanCastCheck("Frost Shock", false))) && GetUnitFrostShockNearby(), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(UnitFrostShockNearby);
                CastSpell("Frost Shock", UnitFrostShockNearby, "FrostShockNearby");
            }));
        }

        private static IEnumerable<WoWUnit> GetAllUnits()
        {
            return ObjectManager.GetObjectsOfType<WoWUnit>(true, true);
        }

        [DllImport("user32.dll")]
        private static extern short GetAsyncKeyState(Keys vKey);
        private static bool GetBestFocus()
        {
            UnitBestFocus = null;
            UnitBestFocus = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderByDescending<WoWUnit, byte>(new Func<WoWUnit, byte>(Classname.TalentSort)).ThenByDescending<WoWUnit, double>(unit => unit.HealthPercent).FirstOrDefault<WoWUnit>(unit => (((unit != null) && unit.IsValid) && (unit != Me.CurrentTarget)) && AttackableNoLoS(unit, 50));
            return BasicCheck(UnitBestFocus);
        }

        private static bool GetBestTarget()
        {
            UnitBestTarget = null;
            if (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
            {
                if (DebuffRootorSnare(Me))
                {
                    UnitBestTarget = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                        orderby unit.CurrentHealth
                        select unit).FirstOrDefault<WoWUnit>(unit => Attackable(unit, 5));
                }
                else
                {
                    UnitBestTarget = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                        orderby unit.CurrentHealth
                        select unit).FirstOrDefault<WoWUnit>(unit => Attackable(unit, 20));
                }
                if (UnitBestTarget == null)
                {
                    UnitBestTarget = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                        orderby unit.Distance
                        select unit).FirstOrDefault<WoWUnit>(unit => Attackable(unit, 60));
                }
            }
            if (UnitBestTarget == null)
            {
                UnitBestTarget = (from unit in FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.CurrentHealth
                    select unit).FirstOrDefault<WoWUnit>(delegate (WoWUnit unit) {
                    if (!(Me.CurrentMap.Name == "Proving Grounds") && (!unit.GotTarget || !IsMyPartyRaidMember(unit.CurrentTarget)))
                    {
                        return false;
                    }
                    return Attackable(unit, 5);
                });
            }
            if (UnitBestTarget == null)
            {
                UnitBestTarget = (from unit in FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.CurrentHealth
                    select unit).FirstOrDefault<WoWUnit>(delegate (WoWUnit unit) {
                    if (!(Me.CurrentMap.Name == "Proving Grounds") && (!unit.GotTarget || !IsMyPartyRaidMember(unit.CurrentTarget)))
                    {
                        return false;
                    }
                    return Attackable(unit, 20);
                });
            }
            if (UnitBestTarget == null)
            {
                UnitBestTarget = (from unit in FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.CurrentHealth
                    select unit).FirstOrDefault<WoWUnit>(delegate (WoWUnit unit) {
                    if (!(Me.CurrentMap.Name == "Proving Grounds") && (!unit.GotTarget || !IsMyPartyRaidMember(unit.CurrentTarget)))
                    {
                        return false;
                    }
                    return Attackable(unit, 40);
                });
            }
            return BasicCheck(UnitBestTarget);
        }

        private static bool GetBestTargetRange()
        {
            UnitBestTarget = null;
            if (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
            {
                UnitBestTarget = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.CurrentHealth
                    select unit).FirstOrDefault<WoWUnit>(unit => Attackable(unit, 30));
                if (UnitBestTarget == null)
                {
                    UnitBestTarget = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                        orderby unit.Distance
                        select unit).FirstOrDefault<WoWUnit>(unit => Attackable(unit, 60));
                }
            }
            else
            {
                UnitBestTarget = (from unit in FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.CurrentHealth
                    select unit).FirstOrDefault<WoWUnit>(delegate (WoWUnit unit) {
                    if (!FacingOverride(unit) || (!(Me.CurrentMap.Name == "Proving Grounds") && (!unit.GotTarget || !IsMyPartyRaidMember(unit.CurrentTarget))))
                    {
                        return false;
                    }
                    return Attackable(unit, 40);
                });
            }
            return BasicCheck(UnitBestTarget);
        }

        internal static string GetCurrentSpec()
        {
            switch (Me.Specialization)
            {
                case WoWSpec.ShamanElemental:
                    CurrentSpec = "Elemental";
                    break;

                case WoWSpec.ShamanEnhancement:
                    CurrentSpec = "Enhancement";
                    break;

                default:
                    CurrentSpec = "Restoration";
                    break;
            }
            return CurrentSpec;
        }

        private static float GetDistance(WoWUnit target)
        {
            if ((target == null) || !target.IsValid)
            {
                return 10000f;
            }
            if (target.CombatReach < 3f)
            {
                return (float) target.Distance;
            }
            return ((((float) target.Distance) - target.CombatReach) + 1f);
        }

        private static float GetDistance(WoWUnit source, WoWUnit target)
        {
            if (((source == null) || !source.IsValid) || ((target == null) || !target.IsValid))
            {
                return 10000f;
            }
            if (target.CombatReach < 3f)
            {
                return source.Location.Distance(target.Location);
            }
            return ((source.Location.Distance(target.Location) - target.CombatReach) + 1f);
        }

        private static bool GetEnemyFreezingTrap()
        {
            EnemyFreezingTrap = null;
            EnemyFreezingTrap = ObjectManager.GetObjectsOfType<WoWDynamicObject>().FirstOrDefault<WoWDynamicObject>(p => (p.Entry == 0xa01) && IsEnemy(p.Caster));
            return ((EnemyFreezingTrap != null) && EnemyFreezingTrap.IsValid);
        }

        private static TimeSpan GetItemCooldown(WoWItem Item)
        {
            if ((Item != null) && Item.Usable)
            {
                return Item.CooldownTimeLeft;
            }
            return TimeSpan.FromMinutes(1.0);
        }

        private static int GetLocalRevision()
        {
            string path = LocalFolder + @"\.svn";
            if (Directory.Exists(path))
            {
                int num = -2147483648;
                string str2 = Directory.GetFiles(path, "wc.db").FirstOrDefault<string>();
                if (!string.IsNullOrEmpty(str2))
                {
                    byte[] bytes = System.IO.File.ReadAllBytes(str2);
                    string input = Encoding.Default.GetString(bytes);
                    Regex regex = new Regex("/!svn/ver/(?'version'[0-9]*)/");
                    foreach (Match match in regex.Matches(input))
                    {
                        int num2;
                        if (int.TryParse(match.Groups["version"].Value, out num2) && (num2 > num))
                        {
                            num = num2;
                        }
                    }
                    if (num > -2147483648)
                    {
                        return num;
                    }
                }
            }
            return 0;
        }

        private static bool GetMyShieldonUnit(WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(delegate (WoWAura aura) {
                if (aura.CreatorGuid != target.Guid)
                {
                    return false;
                }
                if ((aura.SpellId != 0x3ce) && (aura.SpellId != 0x144))
                {
                    return (aura.SpellId == 0xcb9f);
                }
                return true;
            });
        }

        private static bool GetPlayerFriendlyCleanseSpirit()
        {
            PlayerFriendlyCleanseSpirit = null;
            PlayerFriendlyCleanseSpirit = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderByDescending<WoWUnit, double>(new Func<WoWUnit, double>(Classname.CountDebuffCurse)).FirstOrDefault<WoWUnit>(unit => ((CountDebuffCurse(unit) > 0.0) && !DebuffDoNotCleanse(unit)) && Healable(unit, 40));
            return BasicCheck(PlayerFriendlyCleanseSpirit);
        }

        private static bool GetPlayerFriendlyCleanseSpiritASAP()
        {
            PlayerFriendlyCleanseSpiritASAP = null;
            PlayerFriendlyCleanseSpiritASAP = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (!DebuffDoNotCleanse(unit) && UnitHasAura("Hex", unit)) && Healable(unit, 40));
            return BasicCheck(PlayerFriendlyCleanseSpiritASAP);
        }

        private static bool GetPlayerFriendlyPurifySpirit()
        {
            GetPlayerFriendlyPurifySpiritLast = DateTime.Now + TimeSpan.FromMilliseconds(1000.0);
            PlayerFriendlyPurifySpirit = null;
            PlayerFriendlyPurifySpirit = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderByDescending<WoWUnit, double>(new Func<WoWUnit, double>(Classname.CountDebuff)).FirstOrDefault<WoWUnit>(unit => ((CountDebuff(unit) >= THSettings.Instance.PurifySpiritDebuffNumber) && !DebuffDoNotCleanse(unit)) && Healable(unit, 40));
            return BasicCheck(PlayerFriendlyPurifySpirit);
        }

        private static bool GetPlayerFriendlyPurifySpiritASAP()
        {
            PlayerFriendlyPurifySpiritASAP = null;
            if (!THSettings.Instance.PurifySpiritASAP || !Me.Combat)
            {
                return false;
            }
            PlayerFriendlyPurifySpiritASAP = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (DebuffCCleanseASAP(unit) && !DebuffDoNotCleanse(unit)) && Healable(unit, 40));
            return BasicCheck(PlayerFriendlyPurifySpiritASAP);
        }

        private static bool GetPlayerHealingRain()
        {
            PlayerHealingRain = null;
            PlayerHealingRain = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderByDescending<WoWUnit, double>(new Func<WoWUnit, double>(Classname.CountUnitHealingRain)).ThenBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.HealWeight)).FirstOrDefault<WoWUnit>(unit => (((unit.Distance <= 40.0) && (unit.HealthPercent <= THSettings.Instance.HealingRainHP)) && (CountUnitHealingRain(unit) >= THSettings.Instance.HealingRainUnit)) && Healable(unit, 40));
            if ((PlayerHealingRain == null) && Me.CurrentMap.IsRaid)
            {
                PlayerHealingRain = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderByDescending<WoWUnit, double>(new Func<WoWUnit, double>(Classname.CountUnitHealingRainNear)).FirstOrDefault<WoWUnit>(unit => ((unit.Distance <= 40.0) && HasTankNear(unit)) && Healable(unit, 40));
            }
            return BasicCheck(PlayerHealingRain);
        }

        private static double GetSpellCastTime(int spell)
        {
            SpellFindResults results;
            if (!SpellManager.FindSpell(spell, out results))
            {
                return 99999.9;
            }
            if (results.Override == null)
            {
                return (((double) results.Original.CastTime) / 1000.0);
            }
            return (((double) results.Override.CastTime) / 1000.0);
        }

        private static double GetSpellCastTime(string spell)
        {
            SpellFindResults results;
            if (!SpellManager.FindSpell(spell, out results))
            {
                return 99999.9;
            }
            if (results.Override == null)
            {
                return (((double) results.Original.CastTime) / 1000.0);
            }
            return (((double) results.Override.CastTime) / 1000.0);
        }

        public static TimeSpan GetSpellCooldown(int spell, int indetermValue = 0x7fffffff)
        {
            SpellFindResults results;
            if (SpellManager.FindSpell(spell, out results))
            {
                return (results.Override ?? results.Original).CooldownTimeLeft;
            }
            if (indetermValue == 0x7fffffff)
            {
                return TimeSpan.MaxValue;
            }
            return TimeSpan.FromSeconds((double) indetermValue);
        }

        public static TimeSpan GetSpellCooldown(string spell, int indetermValue = 0x7fffffff)
        {
            SpellFindResults results;
            if (SpellManager.FindSpell(spell, out results))
            {
                return (results.Override ?? results.Original).CooldownTimeLeft;
            }
            if (indetermValue == 0x7fffffff)
            {
                return TimeSpan.MaxValue;
            }
            return TimeSpan.FromSeconds((double) indetermValue);
        }

        private static double GetSpellPowerCost(int spell)
        {
            SpellFindResults results;
            if (SpellManager.FindSpell(spell, out results))
            {
                return ((results.Override != null) ? ((double) results.Override.PowerCost) : ((double) results.Original.PowerCost));
            }
            return 99999.9;
        }

        private static double GetSpellPowerCost(string spell)
        {
            SpellFindResults results;
            if (SpellManager.FindSpell(spell, out results))
            {
                return ((results.Override != null) ? ((double) results.Override.PowerCost) : ((double) results.Original.PowerCost));
            }
            return 99999.9;
        }

        private static int GetSVNRevision()
        {
            string input = new WebClient().DownloadString("https://tuanha.sourcerepo.com/tuanha/tuanhashamanspecialedition.5.4/");
            Match match = new Regex(@" - Revision (?<rev>\d+):", RegexOptions.CultureInvariant).Match(input);
            if (!match.Success || !match.Groups["rev"].Success)
            {
                throw new Exception("Unable to retreive revision");
            }
            return int.Parse(match.Groups["rev"].Value);
        }

        private static bool GetUnitAttackingMyPet()
        {
            UnitAttackingMyPet = null;
            UnitAttackingMyPet = (from unit in FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                orderby unit.ThreatInfo.RawPercent descending
                select unit).FirstOrDefault<WoWUnit>(delegate (WoWUnit unit) {
                if ((!MyAura("Hex", unit) || unit.IsPlayer) || unit.IsPet)
                {
                    if (!unit.Combat || !unit.GotTarget)
                    {
                        return false;
                    }
                    if (unit.CurrentTarget != Me)
                    {
                        return unit.CurrentTarget.CreatedByUnit == Me;
                    }
                }
                return true;
            });
            return BasicCheck(UnitAttackingMyPet);
        }

        private static bool GetUnitAttackRestoAny()
        {
            UnitAttackRestoAny = null;
            UnitAttackRestoAny = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                orderby unit.HealthPercent
                select unit).FirstOrDefault<WoWUnit>(unit => (((unit.HealthPercent <= THSettings.Instance.AttackRestoAnyHP) && !InvulnerableSpell(unit)) && FacingOverride(unit)) && Attackable(unit, 30));
            if (UnitAttackRestoAny == null)
            {
                UnitAttackRestoAny = (from unit in FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.HealthPercent
                    select unit).FirstOrDefault<WoWUnit>(unit => (((Me.CurrentMap.Name == "Proving Grounds") || ((unit.Combat && unit.GotTarget) && FarFriendlyPlayers.Contains(unit.CurrentTarget))) && (((unit.HealthPercent <= THSettings.Instance.AttackRestoAnyHP) && !InvulnerableSpell(unit)) && FacingOverride(unit))) && Attackable(unit, 30));
            }
            return BasicCheck(UnitAttackRestoAny);
        }

        private static bool GetUnitAttackRTelluricCurrents()
        {
            UnitAttackRTelluricCurrents = null;
            if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
            {
                UnitAttackRTelluricCurrents = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.HealthPercent
                    select unit).FirstOrDefault<WoWUnit>(unit => (((unit.MaxHealth > (MeMaxHealth * 0.5)) && !InvulnerableSpell(unit)) && FacingOverride(unit)) && Attackable(unit, 30));
            }
            if (UnitAttackRTelluricCurrents == null)
            {
                UnitAttackRTelluricCurrents = (from unit in NearbyUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.HealthPercent descending
                    select unit).FirstOrDefault<WoWUnit>(unit => ((((Me.CurrentMap.Name == "Proving Grounds") || IsDummy(unit)) || (unit.Combat && (unit.MaxHealth > (MeMaxHealth * 0.5)))) && ((!InvulnerableSpell(unit) && FacingOverride(unit)) && (unit.GotTarget && FarFriendlyPlayers.Contains(unit.CurrentTarget)))) && Attackable(unit, 30));
            }
            return BasicCheck(UnitAttackRTelluricCurrents);
        }

        private static bool GetUnitAutoAttack()
        {
            UnitAutoAttack = null;
            UnitAutoAttack = FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((unit != Me.CurrentTarget) && Me.IsFacing(unit)) && (GetDistance(unit) <= 5f)) && Attackable(unit, 5));
            return BasicCheck(UnitAutoAttack);
        }

        private static bool GetUnitAutoRez()
        {
            AutoRezListCacheClear();
            UnitAutoRez = null;
            UnitAutoRez = (from unit in ObjectManager.GetObjectsOfType<WoWPlayer>()
                orderby unit.Distance
                select unit).FirstOrDefault<WoWPlayer>(p => ((!AutoRezListCache.ContainsKey(p.Guid) && p.IsPlayer) && (!p.IsAlive && (p.Distance < 100.0))) && p.IsInMyPartyOrRaid);
            return ((UnitAutoRez != null) && UnitAutoRez.IsValid);
        }

        private static bool GetUnitCapacitorEnemyDefault()
        {
            UnitCapacitorEnemyDefault = null;
            if (THSettings.Instance.CapacitorProjection && SpellManager.HasSpell("Totemic Projection"))
            {
                UnitCapacitorEnemyDefault = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderByDescending<WoWUnit, byte>(new Func<WoWUnit, byte>(Classname.TalentSort)).ThenByDescending<WoWUnit, double>(unit => unit.HealthPercent).FirstOrDefault<WoWUnit>(unit => ((!InvulnerableSpell(unit) && !DebuffCCDuration(unit, 3000.0, false)) && (!InvulnerableStun(unit) && (GetDistance(unit) <= 40f))) && InLineOfSpellSightCheck(unit));
            }
            return BasicCheck(UnitCapacitorEnemyDefault);
        }

        private static bool GetUnitCapacitorEnemyDPS()
        {
            UnitCapacitorEnemyDPS = null;
            if (THSettings.Instance.CapacitorProjection && SpellManager.HasSpell("Totemic Projection"))
            {
                UnitCapacitorEnemyDPS = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.HealthPercent
                    select unit).FirstOrDefault<WoWUnit>(unit => (((!InvulnerableSpell(unit) && !InvulnerableStun(unit)) && ((TalentSort(unit) < 4) && !DebuffCCDuration(unit, 3000.0, false))) && (GetDistance(unit) <= 40f)) && InLineOfSpellSightCheck(unit));
            }
            return BasicCheck(UnitCapacitorEnemyDPS);
        }

        private static bool GetUnitCapacitorEnemyHealer()
        {
            UnitCapacitorEnemyHealer = null;
            if (THSettings.Instance.CapacitorProjection && SpellManager.HasSpell("Totemic Projection"))
            {
                UnitCapacitorEnemyHealer = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.HealthPercent descending
                    select unit).FirstOrDefault<WoWUnit>(unit => (((!InvulnerableSpell(unit) && !InvulnerableStun(unit)) && ((TalentSort(unit) > 3) && !DebuffCCDuration(unit, 3000.0, false))) && (GetDistance(unit) <= 40f)) && InLineOfSpellSightCheck(unit));
            }
            return BasicCheck(UnitCapacitorEnemyHealer);
        }

        private static bool GetUnitCapacitorEnemyPack()
        {
            UnitCapacitorEnemyPack = null;
            if (THSettings.Instance.CapacitorProjection && SpellManager.HasSpell("Totemic Projection"))
            {
                UnitCapacitorEnemyPack = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.CountEnemyPlayerNearCapacitor)).FirstOrDefault<WoWUnit>(unit => (((!InvulnerableSpell(unit) && !InvulnerableStun(unit)) && (!DebuffCCDuration(unit, 3000.0, false) && (GetDistance(unit) <= 40f))) && (CountEnemyPlayerNearCapacitor(unit) >= THSettings.Instance.CapacitorEnemyPackNumber)) && InLineOfSpellSightCheck(unit));
            }
            else if (CountEnemyPlayerNearCapacitor(Me) > THSettings.Instance.CapacitorEnemyPackNumber)
            {
                UnitCapacitorEnemyPack = Me;
            }
            return BasicCheck(UnitCapacitorEnemyPack);
        }

        private static bool GetUnitDispellerAround()
        {
            UnitDispellerAround = null;
            UnitDispellerAround = (from unit in (from unit in FarUnFriendlyUnits
                orderby unit.Distance
                where unit.IsPlayer
                select unit).Where<WoWUnit>(delegate (WoWUnit unit) {
                if (((unit.Class != WoWClass.Hunter) && (unit.Class != WoWClass.Mage)) && (unit.Class != WoWClass.Priest))
                {
                    return unit.Class == WoWClass.Shaman;
                }
                return true;
            })
                where AttackableNoLoS(unit, 40)
                select unit).FirstOrDefault<WoWUnit>();
            return BasicCheck(UnitDispellerAround);
        }

        private static bool GetUnitEarthquake()
        {
            UnitEarthquake = null;
            UnitEarthquake = FarFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderByDescending<WoWUnit, double>(new Func<WoWUnit, double>(Classname.CountUnitEarthquake)).ThenByDescending<WoWUnit, double>(unit => unit.HealthPercent).FirstOrDefault<WoWUnit>(unit => ((unit.Distance <= 40.0) && (CountUnitEarthquake(unit) >= THSettings.Instance.EarthquakeUnit)) && Attackable(unit, 40));
            return BasicCheck(UnitEarthquake);
        }

        private static bool GetUnitEarthShield()
        {
            UnitEarthShield = null;
            UnitEarthShield = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.HealWeight)).FirstOrDefault<WoWUnit>(unit => ((unit != Me) && !UnitHasAura("Earth Shield", unit)) && Healable(unit, 40));
            return BasicCheck(UnitEarthShield);
        }

        private static bool GetUnitFlameShock55447()
        {
            UnitFlameShock55447 = null;
            UnitFlameShock55447 = (from unit in FarFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                orderby unit.HealthPercent descending
                select unit).FirstOrDefault<WoWUnit>(unit => ((((Me.CurrentMap.Name == "Proving Grounds") || IsDummy(unit)) || ((unit.GotTarget && FarFriendlyPlayers.Contains(unit.CurrentTarget)) && (unit.MaxHealth > (MeMaxHealth * 0.5)))) && ((FacingOverride(unit) && !MyAura("Flame Shock", unit)) && !InvulnerableSpell(unit))) && Attackable(unit, (int) SpellManager.Spells["Flame Shock"].MaxRange));
            return BasicCheck(UnitFlameShock55447);
        }

        private static bool GetUnitFlameShockAoE()
        {
            UnitFlameShockAoE = null;
            if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
            {
                UnitFlameShockAoE = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.HealthPercent
                    select unit).FirstOrDefault<WoWUnit>(unit => (((unit.MaxHealth > (MeMaxHealth * 0.5)) && Me.IsFacing(unit)) && (!MyAura("Flame Shock", unit) && !InvulnerableSpell(unit))) && Attackable(unit, ((int) SpellManager.Spells["Flame Shock"].MaxRange) - 3));
            }
            else
            {
                UnitFlameShockAoE = (from unit in NearbyUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.HealthPercent descending
                    select unit).FirstOrDefault<WoWUnit>(unit => ((((Me.CurrentMap.Name == "Proving Grounds") || IsDummy(unit)) || ((unit.GotTarget && FarFriendlyPlayers.Contains(unit.CurrentTarget)) && ((unit.CurrentHealth > (MeMaxHealth * 0.5)) && unit.Combat))) && ((Me.IsFacing(unit) && !MyAura("Flame Shock", unit)) && !InvulnerableSpell(unit))) && Attackable(unit, ((int) SpellManager.Spells["Flame Shock"].MaxRange) - 3));
            }
            return BasicCheck(UnitFlameShockAoE);
        }

        private static bool GetUnitFlameShockRogueDruid()
        {
            UnitFlameShockRogueDruid = null;
            UnitFlameShockRogueDruid = (from unit in NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                orderby MyAuraTimeLeft("Flame Shock", unit)
                select unit).FirstOrDefault<WoWUnit>(unit => ((((TalentSort(unit) < 2) && ((unit.Class == WoWClass.Rogue) || (unit.Class == WoWClass.Druid))) && (((unit.CurrentTarget == null) || (unit.GotTarget && (unit.CurrentTarget != Me))) || ((unit.GotTarget && (unit.CurrentTarget == Me)) && DebuffRoot(unit)))) && ((!unit.Combat || !DebuffDotDuration(unit, 0x1770)) && !InvulnerableSpell(unit))) && Attackable(unit, (int) SpellManager.Spells["Flame Shock"].MaxRange));
            return BasicCheck(UnitFlameShockRogueDruid);
        }

        private static bool GetUnitFrostShockNearby()
        {
            UnitFrostShockNearby = null;
            UnitFrostShockNearby = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, byte>(new Func<WoWUnit, byte>(Classname.TalentSort)).ThenBy<WoWUnit, double>(unit => unit.Distance).FirstOrDefault<WoWUnit>(unit => (((((THSettings.Instance.FrostShockNearbyMelee && (TalentSort(unit) < 2)) || ((THSettings.Instance.FrostShockNearbyRange && (TalentSort(unit) < 4)) && (TalentSort(unit) > 1))) || (THSettings.Instance.FrostShockNearbyHealer && (TalentSort(unit) > 3))) && (FacingOverride(unit) && ((SpellManager.HasSpell("Frozen Power") && !DebuffRoot(unit)) || !DebuffRootorSnare(unit)))) && (!InvulnerableSpell(unit) && !InvulnerableRootandSnare(unit))) && Attackable(unit, (int) SpellManager.Spells["Frost Shock"].MaxRange));
            return BasicCheck(UnitFrostShockNearby);
        }

        private static bool GetUnitGhostWolfCastingCC()
        {
            UnitGhostWolfCC = null;
            if (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
            {
                UnitGhostWolfCC = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => ((unit.Distance <= 30.0) && IsCastingCCGhostWolfImmune(unit)) && InLineOfSpellSightCheck(unit));
            }
            return BasicCheck(UnitGhostWolfCC);
        }

        private static bool GetUnitGroundingCast()
        {
            UnitGroundingCast = null;
            if (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
            {
                UnitGroundingCast = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((unit.Distance < 30.0) && (TalentSort(unit) < 4)) && !unit.IsCastingHealingSpell) && InterruptCheckGrounding(unit, (double) THSettings.Instance.GroundingCastMs));
            }
            return BasicCheck(UnitGroundingCast);
        }

        private static bool GetUnitGroundingLow(WoWUnit target)
        {
            UnitGroundingLow = null;
            UnitGroundingLow = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((unit.GotTarget && (unit.CurrentTarget == target)) && ((unit.Distance < 30.0) && (TalentSort(unit) < 4))) && (unit.Class != WoWClass.Rogue)) && (unit.Class != WoWClass.Warrior));
            return BasicCheck(UnitGroundingLow);
        }

        private static bool GetUnitHasMyEarthShield()
        {
            if ((GetUnitHasMyEarthShieldLast > DateTime.Now) && BasicCheck(UnitHasMyEarthShield))
            {
                return true;
            }
            UnitHasMyEarthShield = null;
            GetUnitHasMyEarthShieldLast = DateTime.Now + TimeSpan.FromMilliseconds(3000.0);
            UnitHasMyEarthShield = FarFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => MyAura("Earth Shield", unit));
            return BasicCheck(UnitHasMyEarthShield);
        }

        private static bool GetUnitHaveMySacredShield()
        {
            UnitHaveMySacredShield = null;
            UnitHaveMySacredShield = (from unit in FarFriendlyPlayers
                where MyAura(0x51bd, unit)
                select unit).FirstOrDefault<WoWUnit>();
            return BasicCheck(UnitHaveMySacredShield);
        }

        private static Composite GetUnitHeal()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                UnitHeal = null;
                UnitHealIsValid = false;
                HealWeightUnitHeal = 10000.0;
                if (((((UnitHeal == null) && (Me.CurrentTarget != null)) && (Me.CurrentTarget.IsValid && Me.CurrentTarget.IsAlive)) && ((GetDistance(Me.CurrentTarget) < 40f) && ((Me.CurrentTarget.IsPlayer || Me.CurrentTarget.IsPet) || NeedHealUnit(Me.CurrentTarget)))) && (((Me.CurrentTarget.HealthPercent <= THSettings.Instance.DoNotHealAbove) && !IsEnemy(Me.CurrentTarget)) && (!DebuffDoNotHeal(Me.CurrentTarget) && InLineOfSpellSightCheck(Me.CurrentTarget))))
                {
                    UnitHeal = Me.CurrentTarget;
                }
                if (((((UnitHeal == null) && (Me.FocusedUnit != null)) && (Me.FocusedUnit.IsValid && Me.FocusedUnit.IsAlive)) && ((GetDistance(Me.FocusedUnit) < 40f) && ((Me.FocusedUnit.IsPlayer || Me.FocusedUnit.IsPet) || NeedHealUnit(Me.FocusedUnit)))) && (((Me.FocusedUnit.HealthPercent <= THSettings.Instance.PriorityHeal) && !IsEnemy(Me.FocusedUnit)) && (!DebuffDoNotHeal(Me.FocusedUnit) && InLineOfSpellSightCheck(Me.FocusedUnit))))
                {
                    UnitHeal = Me.FocusedUnit;
                }
                if ((!Me.CurrentMap.IsArena && (UnitHeal == null)) && (Me.HealthPercent < THSettings.Instance.PriorityHeal))
                {
                    UnitHeal = Me;
                }
                if (Me.CurrentMap.IsArena && (UnitHeal == null))
                {
                    UnitHeal = (from unit in NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                        orderby unit.HealthPercent
                        select unit).FirstOrDefault<WoWUnit>(unit => (((GetDistance(unit) <= 40f) && !DebuffDoNotHeal(unit)) && (unit.HealthPercent < THSettings.Instance.PriorityHeal)) && InLineOfSpellSightCheck(unit));
                }
                if (Me.CurrentMap.IsArena && (UnitHeal == null))
                {
                    UnitHeal = (from unit in NearbyFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                        orderby unit.HealthPercent
                        select unit).FirstOrDefault<WoWUnit>(unit => (((unit.IsPlayer || unit.IsBeast) || (unit.IsDemon || unit.IsUndead)) && (((unit.MaxHealth > (MeMaxHealth / 3.0)) && (GetDistance(unit) <= 40f)) && !DebuffDoNotHeal(unit))) && InLineOfSpellSightCheck(unit));
                }
                if (UnitHeal == null)
                {
                    UnitHeal = (from unit in NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                        orderby unit.HealthPercent
                        select unit).FirstOrDefault<WoWUnit>(unit => ((GetDistance(unit) <= 40f) && !DebuffDoNotHeal(unit)) && InLineOfSpellSightCheck(unit));
                }
                if (UnitHeal == null)
                {
                    UnitHealIsValid = false;
                }
                else
                {
                    UnitHealIsValid = true;
                    HealWeightUnitHeal = HealWeight(UnitHeal);
                }
                return RunStatus.Failure;
            });
        }

        private static bool GetUnitNeedTremor()
        {
            return NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(delegate (WoWUnit unit) {
                if ((unit.Distance > 29.0) || (((!THSettings.Instance.TremorMe || (unit != Me)) && (!THSettings.Instance.TremorHealer || (TalentSort(unit) <= 3))) && (!THSettings.Instance.TremorDPS || (TalentSort(unit) >= 4))))
                {
                    return false;
                }
                return NeedTremor(unit, THSettings.Instance.TremorDuration, true);
            });
        }

        private static Composite GetUnits()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                EnemyListCacheClear();
                FriendListCacheClear();
                NearbyFriendlyPlayers.Clear();
                NearbyFriendlyUnits.Clear();
                FarFriendlyPlayers.Clear();
                FarFriendlyUnits.Clear();
                NearbyUnFriendlyPlayers.Clear();
                NearbyUnFriendlyUnits.Clear();
                FarUnFriendlyPlayers.Clear();
                FarUnFriendlyUnits.Clear();
                foreach (WoWUnit unit in from unit in GetAllUnits()
                    where ((unit.CanSelect && unit.IsAlive) && (GetDistance(unit) < 60f)) && !Blacklist.Contains(unit.Guid, BlacklistFlags.All)
                    select unit)
                {
                    if (IsMyPartyRaidMember(unit))
                    {
                        WoWPlayer player = unit as WoWPlayer;
                        if ((player != null) || NeedHealUnit(unit))
                        {
                            FarFriendlyPlayers.Add(unit);
                            FarFriendlyUnits.Add(unit);
                            if (unit.Distance <= 40.0)
                            {
                                NearbyFriendlyUnits.Add(unit);
                                NearbyFriendlyPlayers.Add(unit);
                            }
                        }
                        else
                        {
                            FarFriendlyUnits.Add(unit);
                            if (unit.Distance <= 40.0)
                            {
                                NearbyFriendlyUnits.Add(unit);
                            }
                        }
                    }
                    else if (IsEnemy(unit))
                    {
                        WoWPlayer player2 = unit as WoWPlayer;
                        if (player2 != null)
                        {
                            FarUnFriendlyPlayers.Add(unit);
                            FarUnFriendlyUnits.Add(unit);
                            if (unit.Distance <= 40.0)
                            {
                                NearbyUnFriendlyUnits.Add(unit);
                                NearbyUnFriendlyPlayers.Add(unit);
                            }
                        }
                        else
                        {
                            FarUnFriendlyUnits.Add(unit);
                            if (unit.Distance <= 40.0)
                            {
                                NearbyUnFriendlyUnits.Add(unit);
                            }
                        }
                    }
                }
                return RunStatus.Failure;
            });
        }

        private static bool GetUnitTankHasMyEarthShield()
        {
            UnitTankHasMyEarthShield = null;
            UnitTankHasMyEarthShield = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.HealWeight)).FirstOrDefault<WoWUnit>(unit => IsTank(unit) && MyAura("Earth Shield", unit));
            return BasicCheck(UnitTankHasMyEarthShield);
        }

        private static bool GetUnitTankToEarthShield()
        {
            UnitTankToEarthShield = null;
            UnitTankToEarthShield = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.HealWeight)).FirstOrDefault<WoWUnit>(unit => IsTank(unit) && !UnitHasAura("Earth Shield", unit));
            return BasicCheck(UnitTankToEarthShield);
        }

        private static bool GetUnitThuderstormInterrupt()
        {
            UnitThuderstormInterrupt = null;
            if (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
            {
                UnitThuderstormInterrupt = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((THSettings.Instance.InterruptAll || ((THSettings.Instance.InterruptTarget && (Me.CurrentTarget != null)) && (unit == Me.CurrentTarget))) || ((THSettings.Instance.InterruptFocus && (Me.FocusedUnit != null)) && (unit == Me.FocusedUnit))) && InterruptCheck(unit, (double) THSettings.Instance.ThunderstormCastMs, false)) && Attackable(unit, 10));
            }
            else
            {
                UnitThuderstormInterrupt = NearbyUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((THSettings.Instance.InterruptAll || ((THSettings.Instance.InterruptTarget && (Me.CurrentTarget != null)) && (unit == Me.CurrentTarget))) || ((THSettings.Instance.InterruptFocus && (Me.FocusedUnit != null)) && (unit == Me.FocusedUnit))) && (((Me.CurrentMap.Name == "Proving Grounds") || ((unit.Combat && unit.GotTarget) && FarFriendlyPlayers.Contains(unit.CurrentTarget))) && InterruptCheck(unit, (double) THSettings.Instance.ThunderstormCastMs, false))) && Attackable(unit, 10));
            }
            return BasicCheck(UnitThuderstormInterrupt);
        }

        private static bool GetUnitUnitBindElemental()
        {
            UnitBindElemental = null;
            UnitBindElemental = (from unit in NearbyUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                orderby unit.CurrentHealth descending
                select unit).FirstOrDefault<WoWUnit>(unit => (((unit.IsElemental && unit.Combat) && (NearbyFriendlyPlayers.Contains(unit.CurrentTarget) && !UnitHasAura("Bind Elemental", unit))) && !DebuffCC(unit)) && Attackable(unit, 30));
            return BasicCheck(UnitBindElemental);
        }

        private static bool GetUnitUnitHex()
        {
            UnitHex = null;
            if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
            {
                UnitHex = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderByDescending<WoWUnit, byte>(new Func<WoWUnit, byte>(Classname.TalentSortSimple)).ThenBy<WoWUnit, int>(new Func<WoWUnit, int>(Classname.CountFriendDPSTarget)).ThenByDescending<WoWUnit, double>(unit => unit.HealthPercent).FirstOrDefault<WoWUnit>(unit => (((THSettings.Instance.HexHealer && (TalentSort(unit) > 3)) || (THSettings.Instance.HexDPS && (TalentSort(unit) < 4))) && (((UseSpecialization == 3) || ((UseSpecialization != 3) && (unit != Me.CurrentTarget))) && ((CanHex(unit) && !DebuffCCDuration(unit, 2000.0, false)) && !InvulnerableSpell(unit)))) && Attackable(unit, 30));
            }
            else
            {
                UnitHex = (from unit in FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck))
                    orderby unit.CurrentHealth descending
                    select unit).ThenBy<WoWUnit, int>(new Func<WoWUnit, int>(Classname.CountFriendDPSTarget)).FirstOrDefault<WoWUnit>(unit => ((((unit.Combat && !unit.IsBoss) && (unit.IsHumanoid || unit.IsBeast)) && ((Me.CurrentMap.Name == "Proving Grounds") || (unit.GotTarget && FarFriendlyPlayers.Contains(unit.CurrentTarget)))) && (unit != Me.CurrentTarget)) && Attackable(unit, 30));
            }
            return BasicCheck(UnitHex);
        }

        private static bool GetUnitUnitPurgeASAPResto()
        {
            UnitPurgeASAPResto = null;
            UnitPurgeASAPResto = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.HealWeight)).FirstOrDefault<WoWUnit>(unit => NeedPurgeASAPResto(unit) && Attackable(unit, 30));
            return BasicCheck(UnitPurgeASAPResto);
        }

        private static bool GetUnitUnitPurgeNormalResto()
        {
            UnitPurgeNormalResto = null;
            if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
            {
                UnitPurgeNormalResto = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, int>(new Func<WoWUnit, int>(Classname.CountFriendDPSTarget)).FirstOrDefault<WoWUnit>(unit => (CountMagicBuffPurge(unit) > 0) && Attackable(unit, 30));
            }
            if (UnitPurgeNormalResto == null)
            {
                UnitPurgeNormalResto = FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, int>(new Func<WoWUnit, int>(Classname.CountFriendDPSTarget)).FirstOrDefault<WoWUnit>(unit => (((Me.CurrentMap.Name == "Proving Grounds") || (unit.GotTarget && FarFriendlyPlayers.Contains(unit.CurrentTarget))) && (CountMagicBuffPurge(unit) > 0)) && Attackable(unit, 30));
            }
            return BasicCheck(UnitPurgeNormalResto);
        }

        private static bool GetUnitUnitRiptide()
        {
            UnitRiptide = null;
            if ((Me.CurrentMap.IsDungeon || Me.CurrentMap.IsRaid) || ((Me.CurrentMap.Name == "Proving Grounds") || HasGlyph.Contains("63273")))
            {
                UnitRiptide = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => ((unit.Combat && (UnitHasAura("Vengeance", unit) || ((Me.CurrentMap.Name == "Proving Grounds") && (unit.Entry == 0x11a1a)))) && (!MyAura(0xef6f, unit) && (HealWeight(unit) < 100.0))) && Healable(unit, 40));
                if (UnitRiptide == null)
                {
                    UnitRiptide = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.HealWeight)).FirstOrDefault<WoWUnit>(unit => ((HealWeight(unit) <= THSettings.Instance.RiptideHP) && !MyAura(0xef6f, unit)) && Healable(unit, 40));
                }
            }
            else if (Me.CurrentMap.IsArena)
            {
                UnitRiptide = NearbyFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.HealWeight)).FirstOrDefault<WoWUnit>(unit => ((unit.IsPlayer || (unit.IsPet && (unit.MaxHealth > (MeMaxHealth * 0.5)))) && ((HealWeight(unit) <= THSettings.Instance.RiptideHP) && (!MyAura(0xef6f, unit) || (HealWeight(unit) <= THSettings.Instance.PriorityHeal)))) && Healable(unit, 40));
            }
            else
            {
                UnitRiptide = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).OrderBy<WoWUnit, double>(new Func<WoWUnit, double>(Classname.HealWeight)).FirstOrDefault<WoWUnit>(delegate (WoWUnit unit) {
                    if ((HealWeight(unit) > THSettings.Instance.RiptideHP) || (MyAura(0xef6f, unit) && (HealWeight(unit) > THSettings.Instance.RiptideHP)))
                    {
                        return false;
                    }
                    return Healable(unit, 40);
                });
            }
            return BasicCheck(UnitRiptide);
        }

        private static bool GetUnitWarStomp()
        {
            UnitWarStomp = null;
            if (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
            {
                UnitWarStomp = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((THSettings.Instance.InterruptAll || ((THSettings.Instance.InterruptTarget && (Me.CurrentTarget != null)) && (unit == Me.CurrentTarget))) || ((THSettings.Instance.InterruptFocus && (Me.FocusedUnit != null)) && (unit == Me.FocusedUnit))) && InterruptCheck(unit, 2000.0, true)) && Attackable(unit, 8));
            }
            else
            {
                UnitWarStomp = NearbyUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((THSettings.Instance.InterruptAll || ((THSettings.Instance.InterruptTarget && (Me.CurrentTarget != null)) && (unit == Me.CurrentTarget))) || ((THSettings.Instance.InterruptFocus && (Me.FocusedUnit != null)) && (unit == Me.FocusedUnit))) && (((Me.CurrentMap.Name == "Proving Grounds") || ((unit.Combat && unit.GotTarget) && FarFriendlyPlayers.Contains(unit.CurrentTarget))) && InterruptCheck(unit, 2000.0, true))) && Attackable(unit, 8));
            }
            return BasicCheck(UnitWarStomp);
        }

        private static bool GetUnitWindShear()
        {
            UnitWindShear = null;
            if (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)
            {
                UnitWindShear = NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((THSettings.Instance.InterruptAll || ((THSettings.Instance.InterruptTarget && (Me.CurrentTarget != null)) && (unit == Me.CurrentTarget))) || ((THSettings.Instance.InterruptFocus && (Me.FocusedUnit != null)) && (unit == Me.FocusedUnit))) && InterruptCheck(unit, (double) THSettings.Instance.WindShearInterruptMs, false)) && Attackable(unit, (int) SpellManager.Spells["Wind Shear"].MaxRange));
            }
            else
            {
                UnitWindShear = NearbyUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => (((THSettings.Instance.InterruptAll || ((THSettings.Instance.InterruptTarget && (Me.CurrentTarget != null)) && (unit == Me.CurrentTarget))) || ((THSettings.Instance.InterruptFocus && (Me.FocusedUnit != null)) && (unit == Me.FocusedUnit))) && (((Me.CurrentMap.Name == "Proving Grounds") || ((unit.Combat && unit.GotTarget) && FarFriendlyPlayers.Contains(unit.CurrentTarget))) && InterruptCheck(unit, (double) THSettings.Instance.WindShearInterruptMs, false))) && Attackable(unit, (int) SpellManager.Spells["Wind Shear"].MaxRange));
            }
            return BasicCheck(UnitWindShear);
        }

        private static void GhostWolfAvoidCC()
        {
            if ((THSettings.Instance.AutoGhostWolf && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && (((!MeHasAura("Ghost Wolf") && (LastInterrupt < DateTime.Now)) && (!InvulnerableSpell(Me) && GetUnitGhostWolfCastingCC())) && CanCastCheck("Ghost Wolf", true)))
            {
                if (Me.IsCasting)
                {
                    SpellManager.StopCasting();
                }
                LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(2000.0);
                SpellManager.StopCasting();
                CastSpell("Ghost Wolf", Me, string.Concat(new object[] { "GhostWolfAvoidCC: ", UnitGhostWolfCC.SafeName, " is Casting ", UnitGhostWolfCC.CastingSpell.Name, " - ", UnitGhostWolfCC.CastingSpellId }));
            }
        }

        private static Composite GhostWolfEle()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.AutoGhostWolf || MeHasAura("Ghost Wolf")) || (MeHasAura("Spiritwalker's Grace") || !Me.IsMoving)) || !CanCastCheck("Ghost Wolf", false))
                {
                    return false;
                }
                return !CurrentTargetAttackable(40.0, false, false) || ((GetDistance(Me.CurrentTarget) > 7f) && Me.CurrentTarget.IsSafelyBehind(Me));
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Ghost Wolf", Me, "GhostWolfEle");
            }));
        }

        private static Composite GhostWolfEnh()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.AutoGhostWolf || MeHasAura("Ghost Wolf")) || (MeHasAura("Spiritwalker's Grace") || !Me.IsMoving)) || !CanCastCheck("Ghost Wolf", false))
                {
                    return false;
                }
                return (!CurrentTargetAttackable(10.0, false, false) || ((GetDistance(Me.CurrentTarget) > 7f) && Me.CurrentTarget.IsSafelyBehind(Me))) || ((GetDistance(Me.CurrentTarget) > 5f) && DebuffSnare(Me));
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Ghost Wolf", Me, "GhostWolfEnh");
            }));
        }

        private static Composite GhostWolfHoldComp()
        {
            return new Decorator(ret => !THSettings.Instance.AutoGhostWolfCancel && MeHasAura("Ghost Wolf"), new Styx.TreeSharp.Action(delegate (object param0) {
                Styx.Common.Logging.Write("Auto Cancel Ghost Wolf Disabled");
                return RunStatus.Success;
            }));
        }

        private static Composite GhostWolfResto()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.AutoGhostWolf || MeHasAura("Ghost Wolf")) || (MeHasAura("Spiritwalker's Grace") || !Me.IsMoving)) || !CanCastCheck("Ghost Wolf", false))
                {
                    return false;
                }
                if (!DebuffSnare(Me))
                {
                    return HasMeleeonMe();
                }
                return true;
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Ghost Wolf", Me, "GhostWolfResto");
            }));
        }

        private static void GlobalCheck()
        {
            if (GlobalCheckTime <= DateTime.Now)
            {
                GlobalCheckTime = DateTime.Now + TimeSpan.FromSeconds(30.0);
                UpdateMyLatency();
                UpdateEventHandler();
                if (Me.CurrentMap.IsRaid)
                {
                    CurrentTargetCheckTimeOut = TimeSpan.FromMilliseconds(500.0);
                }
                else if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
                {
                    CurrentTargetCheckTimeOut = TimeSpan.FromMilliseconds(50.0);
                }
                else
                {
                    CurrentTargetCheckTimeOut = TimeSpan.FromMilliseconds(100.0);
                }
            }
        }

        private static Composite GreaterHealingWave()
        {
            return new Decorator(ret => ((THSettings.Instance.GreaterHealingWave && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.GreaterHealingWaveHP) && UnitHeal.Combat)) && CanCastCheck("Greater Healing Wave", false), new Styx.TreeSharp.Action(delegate (object param0) {
                UnleaseElementEarthLiving(THSettings.Instance.UnleashElementsGHW, UnitHeal);
                RiptideTidalWaves(UnitHeal, "RiptideTidalWaves GreaterHealingWave");
                CastSpell("Greater Healing Wave", UnitHeal, "GreaterHealingWave");
            }));
        }

        private static Composite GreaterHealingWaveAS()
        {
            return new Decorator(delegate (object ret) {
                if ((((!THSettings.Instance.AncestralSwiftnessRes || !UnitHealIsValid) || ((HealWeightUnitHeal > THSettings.Instance.AncestralSwiftnessResHP) || MeHasAura(0x3f3c))) || ((!MyAura("Tidal Waves", Me) || !UnitHeal.Combat) || (!HaveDPSTarget(UnitHeal) || Invulnerable(UnitHeal)))) || ((Me.CurrentMana < SpellManager.Spells["Greater Healing Wave"].PowerCost) || (!MeHasAura(0x3f3c) && !CanCastCheck("Ancestral Swiftness", false))))
                {
                    return false;
                }
                return CanCastCheck("Greater Healing Wave", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                UnleaseElementEarthLiving(THSettings.Instance.UnleashElementsGHW, UnitHeal);
                CastSpell("Ancestral Swiftness", Me, "AncestralSwiftnessRes");
                CastSpell("Greater Healing Wave", UnitHeal, "GreaterHealingWaveAS");
            }));
        }

        private static Composite GreaterHealingWaveIsSafetoCast()
        {
            return new Decorator(ret => ((((THSettings.Instance.GreaterHealingWave && UnitHealIsValid) && ((HealWeightUnitHeal < 100.0) && (HealWeightUnitHeal <= (THSettings.Instance.GreaterHealingWaveHP + 10)))) && (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)) && ((UnitHeal.Combat && MeHasAura("Tidal Waves")) && IsSafetoCast())) && CanCastCheck("Greater Healing Wave", false), new Styx.TreeSharp.Action(delegate (object param0) {
                UnleaseElementEarthLiving(THSettings.Instance.UnleashElementsGHW, UnitHeal);
                RiptideTidalWaves(UnitHeal, "RiptideTidalWaves GreaterHealingWaveIsSafetoCast");
                CastSpell("Greater Healing Wave", UnitHeal, "GreaterHealingWaveIsSafetoCast");
            }));
        }

        private static void GroundingCastInterruptVoid()
        {
            if ((THSettings.Instance.GroundingCast && (LastInterrupt < DateTime.Now)) && (CanCastCheck("Grounding Totem", true) && GetUnitGroundingCast()))
            {
                if (Me.IsCasting)
                {
                    SpellManager.StopCasting();
                }
                if (UnitGroundingCast.IsCasting)
                {
                    CastSpell("Grounding Totem", UnitGroundingCast, string.Concat(new object[] { "Casting ", UnitGroundingCast.CastingSpell.Name, " - ", UnitGroundingCast.CastingSpellId }));
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
                }
            }
            if (((THSettings.Instance.GroundingTrap && Me.CurrentMap.IsArena) && ((LastInterrupt < DateTime.Now) && CanCastCheck("Grounding Totem", true))) && ((!IsFriendlyHunterNearby() && GetEnemyFreezingTrap()) && NeedGroudingTrap()))
            {
                if (Me.IsCasting)
                {
                    SpellManager.StopCasting();
                }
                CastSpell("Grounding Totem", GroundingTrapPlayer, "Grounding Totem Freezing Trap base on Trap Scan and Friend Distance to trap <=" + GroundingTrapPlayer.Location.Distance(EnemyFreezingTrap.Location));
                LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
            }
            if ((THSettings.Instance.GroundingTrap && Me.CurrentMap.IsArena) && (((LastTrapEvent + TimeSpan.FromMilliseconds(3000.0)) > DateTime.Now) && CanCastCheck("Grounding Totem", true)))
            {
                if (Me.IsCasting)
                {
                    SpellManager.StopCasting();
                }
                CastSpell("Grounding Totem", Me, "Grounding Totem Freezing Trap base on SPELL_CAST_SUCCESS event");
            }
        }

        private static Composite GroundingLow()
        {
            return new Decorator(ret => ((THSettings.Instance.GroundingLow && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.GroundingLowHP) && CanCastCheck("Grounding Totem", false))) && GetUnitGroundingLow(UnitHeal), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Grounding Totem", Me, "GroundingLow");
            }));
        }

        private static void HandleCombatLogPvP(object sender, LuaEventArgs args)
        {
            string str;
            CombatLogEventArgs args2 = new CombatLogEventArgs(args.EventName, args.FireTimeStamp, args.Args);
            if ((((str = args2.Event) != null) && (str == "SPELL_CAST_SUCCESS")) && ((args2.SourceUnit != null) && IsEnemy(args2.SourceUnit)))
            {
                if ((args2.SpellId == 0xeb20) || (args2.SpellId == 0x5db))
                {
                    Styx.Common.Logging.Write("Found Hunter Drop {0} - {1}", new object[] { args2.SpellName, args2.SpellId });
                    LastTrapEvent = DateTime.Now;
                }
                if (((args2.SpellName == "Disrupting Shout") || (args2.SpellName == "Arcane Torrent")) && (((args2.SourceUnit.Distance <= 10.0) && !MeHasAura("Spiritwalker's Aegis")) && !MeHasAura("Devotion Aura")))
                {
                    Styx.Common.Logging.Write("Incoming AOE Silence {0} - {1} Stop Casting", new object[] { args2.SpellName, args2.SpellId });
                    SpellManager.StopCasting();
                }
                if (InterruptSpellHS.Contains(args2.SpellId))
                {
                    Styx.Common.Logging.Write("InterruptonCooldownUnit Add {0} - {1} - {2} - {3} ", new object[] { args2.SourceUnit.SafeName, args2.SpellName, args2.SpellId, InterruptSpellCooldown(args2.SpellId) - 0x3e8 });
                    if (((args2.DestGuid == MeGuid) && !MeHasAura("Spiritwalker's Aegis")) && !MeHasAura("Devotion Aura"))
                    {
                        Styx.Common.Logging.Write("Incoming SPELL_CAST_SUCCESS {0} - {1} Stop Casting", new object[] { args2.SpellName, args2.SpellId });
                        SpellManager.StopCasting();
                    }
                    InterruptonCooldownUnitAdd(args2.SourceUnit, InterruptSpellCooldown(args2.SpellId) - 0x3e8);
                }
            }
        }

        private static bool HasElementalAround()
        {
            return FarFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(delegate (WoWUnit unit) {
                if (((unit.Entry != 0xee65) && (unit.Entry != 0xee80)) && ((unit.Entry != 0x3bf8) && (unit.Entry != 0x3c4e)))
                {
                    return false;
                }
                return (unit.CreatedByUnit == Me);
            });
        }

        private static bool HasEnemyFlameShock()
        {
            return (FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => MyAura("Flame Shock", unit)) != null);
        }

        private static bool HasEnemyNear(WoWUnit unitCenter, float distance)
        {
            return FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(delegate (WoWUnit unit) {
                if ((!(Me.CurrentMap.Name == "Proving Grounds") && !IsDummy(unit)) && ((!unit.Combat || (unit.MaxHealth <= (MeMaxHealth * 0.2))) || (!unit.GotTarget || !FarFriendlyUnits.Contains(unit.CurrentTarget))))
                {
                    return false;
                }
                return (GetDistance(unitCenter, unit) <= distance);
            });
        }

        private static bool HasEnemyTargettingUnit(WoWUnit target, float distance)
        {
            return FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(delegate (WoWUnit unit) {
                if (((!unit.IsValid || (GetDistance(unit) >= distance)) || ((unit.Level > (target.Level + 3)) || (unit.MaxHealth <= (MeMaxHealth * 0.3)))) || ((unit.CurrentTarget != target) || DebuffCC(unit)))
                {
                    return false;
                }
                return ((target != Me) || ((target == Me) && InLineOfSpellSightCheck(unit)));
            });
        }

        private static bool HasFriendDPSTarget(WoWUnit target)
        {
            Func<WoWUnit, bool> predicate = null;
            if (!Me.CurrentMap.IsArena && !Me.CurrentMap.IsBattleground)
            {
                return NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(unit => (unit.CurrentTarget == target));
            }
            if (predicate == null)
            {
                predicate = delegate (WoWUnit unit) {
                    if (unit.CurrentTarget != target)
                    {
                        return false;
                    }
                    return (((TalentSort(unit) >= 2) && (TalentSort(unit) <= 3)) && (unit.Location.Distance(target.Location) < 40f)) || ((TalentSort(unit) == 1) && (unit.Location.Distance(target.Location) < 15f));
                };
            }
            return NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(predicate);
        }

        private static bool HasImportantTotem()
        {
            for (int i = 0; i < 4; i++)
            {
                if ((Me.Totems[i].Unit != null) && ImportantTotemHS.Contains(Me.Totems[i].Unit.Name))
                {
                    return true;
                }
            }
            return false;
        }

        private static bool HasMeleeonMe()
        {
            return NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(unit => (((unit.Distance < 15.0) && (unit.CurrentTarget == Me)) && (TalentSort(unit) == 1)));
        }

        private static bool HasTankNear(WoWUnit target)
        {
            return FarFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(unit => (((unit.Combat && unit.GotTarget) && (IsEnemy(unit.CurrentTarget) && IsTank(unit))) && (target.Location.Distance(unit.Location) <= 10f)));
        }

        private static bool HasUnitBindElemental()
        {
            UnitBindElemental = null;
            UnitBindElemental = FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => unit.IsElemental && MyAura("Bind Elemental", unit));
            return BasicCheck(UnitBindElemental);
        }

        private static bool HaveDPSTarget(WoWUnit target)
        {
            Func<WoWUnit, bool> predicate = null;
            Func<WoWUnit, bool> func2 = null;
            if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
            {
                if (predicate == null)
                {
                    predicate = unit => (((unit.IsValid && (unit.CurrentTarget == target)) && ((((TalentSort(unit) >= 2) && (TalentSort(unit) <= 3)) && (unit.Location.Distance(target.Location) < 40f)) || ((TalentSort(unit) == 1) && (unit.Location.Distance(target.Location) < 20f)))) && !DebuffCC(unit)) && ((target != Me) || ((target == Me) && InLineOfSpellSightCheck(unit)));
                }
                return NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(predicate);
            }
            if (func2 == null)
            {
                func2 = unit => (unit.IsValid && (unit.CurrentTarget == target)) && !DebuffCC(unit);
            }
            return FarUnFriendlyUnits.Any<WoWUnit>(func2);
        }

        private static bool HaveInterrupterRound(WoWUnit target)
        {
            return FarUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(unit => ((TalentSort(unit) == 1) && (GetDistance(target, unit) < 10f)));
        }

        private static bool HaveWorthyTargetAttackingMe()
        {
            WorthyTargetAttackingMe = FarUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => ((unit.Combat && unit.GotTarget) && (unit.CurrentTarget == Me)) && IsWorthyTarget(unit, 1.0, 0.3));
            return BasicCheck(WorthyTargetAttackingMe);
        }

        private static bool Healable(WoWUnit target, int distance = 40)
        {
            return ((((GetDistance(target) <= distance) && !IsEnemy(target)) && !DebuffDoNotHeal(target)) && InLineOfSpellSightCheck(target));
        }

        private static Composite HealingRain()
        {
            return new Decorator(ret => (((THSettings.Instance.HealingRain && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.HealingRainHP) || (Me.Combat && Me.CurrentMap.IsRaid))) && CanCastCheck("Healing Rain", false)) && GetPlayerHealingRain(), new Styx.TreeSharp.Action(delegate (object param0) {
                UnleaseElementEarthLiving(THSettings.Instance.UnleashElementsHR, PlayerHealingRain);
                CastSpell("Healing Rain", PlayerHealingRain, "HealingRain");
                ObjectManager.Update();
                SpellManager.ClickRemoteLocation(PlayerHealingRain.Location);
            }));
        }

        private static Composite HealingStreamTotem()
        {
            return new Decorator(ret => (((THSettings.Instance.HealingStreamTotem && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.HealingStreamTotemHP) && (UnitHeal.Distance < 35.0))) && ((Me.Combat && !MyTotemWaterCheck(Me, 40)) && CanCastCheck("Healing Stream Totem", false))) && (CountUnitHealingStreamTotem() >= THSettings.Instance.HealingStreamTotemUnit), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Healing Stream Totem", Me, "HealingStreamTotem");
            }));
        }

        private static Composite HealingSurgeInCombatEle()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.HealingSurgeInCombatEle && (LastHealingSurge < DateTime.Now)) && ((!CurrentTargetAttackable(40.0, false, false) || (CurrentTargetAttackable(40.0, false, false) && (Me.CurrentTarget.HealthPercent > THSettings.Instance.UrgentHeal))) || (CurrentTargetAttackable(40.0, false, false) && (Me.CurrentTarget.HealthPercent > Me.HealthPercent)))) && ((Me.HealthPercent <= THSettings.Instance.HealingSurgeInCombatEleHP) && (!THSettings.Instance.HealingSurgeInCombatEleCC || MeHasAura(0x3f76)))) && CanCastCheck("Healing Surge", false), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Healing Surge", Me, "HealingSurgeInCombatEle");
                if (IsUsingAFKBot)
                {
                    DoNotMove = DateTime.Now + TimeSpan.FromMilliseconds(3000.0);
                    LastHealingSurge = DateTime.Now + TimeSpan.FromMilliseconds(5000.0);
                    HoldBotAction("Healing Surge");
                }
            })), new Decorator(ret => ((((THSettings.Instance.HealingSurgeInCombatEleFriend && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.HealingSurgeInCombatEleFriendHP) && (LastHealingSurge < DateTime.Now))) && (!CurrentTargetAttackable(40.0, false, false) || (CurrentTargetAttackable(40.0, false, false) && (Me.CurrentTarget.HealthPercent > THSettings.Instance.UrgentHeal)))) && (!THSettings.Instance.HealingSurgeInCombatEleFriendCC || MeHasAura(0x3f76))) && CanCastCheck("Healing Surge", false), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Healing Surge", UnitHeal, "HealingSurgeInCombatEleFriend");
                if (IsUsingAFKBot)
                {
                    DoNotMove = DateTime.Now + TimeSpan.FromMilliseconds(3000.0);
                    LastHealingSurge = DateTime.Now + TimeSpan.FromMilliseconds(5000.0);
                    HoldBotAction("Healing Surge");
                }
            })) });
        }

        private static Composite HealingSurgeInCombatEnh()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.HealingSurgeInCombatEnh && (LastHealingSurge < DateTime.Now)) && (((((MyAuraStackCount(0xd239, Me) > 4.0) || !CurrentTargetAttackable(20.0, false, false)) || (!CurrentTargetAttackable(5.0, false, false) && DebuffRoot(Me))) || ((CurrentTargetAttackable(20.0, false, false) && (Me.CurrentTarget.HealthPercent > THSettings.Instance.UrgentHeal)) && (Me.ManaPercent > 40.0))) || ((CurrentTargetAttackable(20.0, false, false) && (Me.CurrentTarget.HealthPercent > Me.HealthPercent)) && (Me.ManaPercent > 40.0)))) && ((Me.HealthPercent <= THSettings.Instance.HealingSurgeInCombatEnhHP) && (MyAuraStackCount(0xd239, Me) >= THSettings.Instance.HealingSurgeInCombatEnhStack))) && CanCastCheck("Healing Surge", false), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Healing Surge", Me, "HealingSurgeInCombatEnh");
                if (IsUsingAFKBot)
                {
                    HoldBotAction("Healing Surge");
                }
            })), new Decorator(ret => ((((THSettings.Instance.HealingSurgeInCombatEnhFriend && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.HealingSurgeInCombatEnhHPFriend) && (LastHealingSurge < DateTime.Now))) && (((MyAuraStackCount(0xd239, Me) > 4.0) || (!CurrentTargetAttackable(20.0, false, false) && (Me.ManaPercent > 40.0))) || ((CurrentTargetAttackable(20.0, false, false) && (Me.CurrentTarget.HealthPercent >= THSettings.Instance.UrgentHeal)) && (Me.ManaPercent > 40.0)))) && (MyAuraStackCount(0xd239, Me) >= THSettings.Instance.HealingSurgeInCombatEnhStackFriend)) && CanCastCheck("Healing Surge", false), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Healing Surge", UnitHeal, "HealingSurgeInCombatEnhFriend");
                if (IsUsingAFKBot)
                {
                    HoldBotAction("Healing Surge");
                }
            })) });
        }

        private static Composite HealingSurgeOutCombatEle()
        {
            return new Decorator(ret => (((THSettings.Instance.HealingSurgeOutCombatEle && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.HealingSurgeOutCombatEleHP) && (UseSpecialization == 1))) && CanCastCheck("Healing Surge", false)) && !HaveDPSTarget(UnitHeal), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Healing Surge", UnitHeal, "HealingSurgeOutCombatEle");
                if (IsUsingAFKBot)
                {
                    DoNotMove = DateTime.Now + TimeSpan.FromMilliseconds(3000.0);
                    LastHealingSurge = DateTime.Now + TimeSpan.FromMilliseconds(5000.0);
                    HoldBotAction("Healing Surge");
                }
            }));
        }

        private static Composite HealingSurgeOutCombatEnh()
        {
            return new Decorator(ret => (((THSettings.Instance.HealingSurgeOutCombatEnh && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.HealingSurgeOutCombatEnhHP) && (UseSpecialization == 2))) && ((Me.ManaPercent > 50.0) && CanCastCheck("Healing Surge", false))) && !HaveDPSTarget(Me), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Healing Surge", UnitHeal, "HealingSurgeOutCombatEnh");
                if (IsUsingAFKBot)
                {
                    DoNotMove = DateTime.Now + TimeSpan.FromMilliseconds(3000.0);
                    LastHealingSurge = DateTime.Now + TimeSpan.FromMilliseconds(5000.0);
                    HoldBotAction("Healing Surge");
                }
            }));
        }

        private static Composite HealingSurgeRes()
        {
            return new Decorator(ret => ((THSettings.Instance.HealingSurgeRes && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.HealingSurgeResHP) && UnitHeal.Combat)) && CanCastCheck("Healing Surge", false), new Styx.TreeSharp.Action(delegate (object param0) {
                UnleaseElementEarthLiving(THSettings.Instance.UnleashElementsHS, UnitHeal);
                RiptideTidalWaves(UnitHeal, "RiptideTidalWaves HealingSurgeRes");
                CastSpell("Healing Surge", UnitHeal, "HealingSurgeRes");
            }));
        }

        private static Composite HealingSurgeResIsSafetoCast()
        {
            return new Decorator(ret => ((((THSettings.Instance.HealingSurgeRes && UnitHealIsValid) && ((HealWeightUnitHeal < 100.0) && (HealWeightUnitHeal <= (THSettings.Instance.HealingSurgeResHP + 10)))) && (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)) && ((MeHasAura("Tidal Waves") && IsSafetoCast()) && UnitHeal.Combat)) && CanCastCheck("Healing Surge", false), new Styx.TreeSharp.Action(delegate (object param0) {
                UnleaseElementEarthLiving(THSettings.Instance.UnleashElementsHS, UnitHeal);
                RiptideTidalWaves(UnitHeal, "RiptideTidalWaves HealingSurgeResIsSafetoCast");
                CastSpell("Healing Surge", UnitHeal, "HealingSurgeResIsSafetoCast");
            }));
        }

        private static Composite HealingTideTotem()
        {
            return new Decorator(ret => (((THSettings.Instance.HealingTideTotem && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.HealingTideTotemHP) && (UnitHeal.Distance < 35.0))) && ((!MyTotemCheck("Spirit Link Totem", Me, 40) && !MyTotemCheck("Mana Tide Totem", Me, 40)) && CanCastCheck("Healing Tide Totem", true))) && (CountUnitHealingTideTotem() >= THSettings.Instance.HealingTideTotemUnit), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Healing Tide Totem", Me, "HealingTideTotem");
            }));
        }

        private static Composite HealingWave()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.HealingWave || !UnitHealIsValid) || ((HealWeightUnitHeal > THSettings.Instance.HealingWaveHP) || !SpellManager.HasSpell("Healing Wave"))) || ((Me.CurrentMana <= (SpellManager.Spells["Healing Wave"].PowerCost * 4)) || ((HealWeightUnitHeal < THSettings.Instance.GreaterHealingWaveHP) && (UnitHeal.Combat || Me.Combat))))
                {
                    return false;
                }
                return CanCastCheck("Healing Wave", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                RiptideTidalWaves(UnitHeal, "RiptideTidalWaves HealingWave");
                CastSpell("Healing Wave", UnitHeal, "HealingWave");
            }));
        }

        private static Composite HealingWaveBaitInterrupt()
        {
            return new Decorator(ret => ((THSettings.Instance.HealingWave && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && (((UnitHealIsValid && (HealWeightUnitHeal > THSettings.Instance.HealingWaveHP)) && ((HealingWaveBaitInterruptLast < DateTime.Now) && Me.Combat)) && (UnitHeal.Combat && SpellManager.HasSpell("Healing Wave")))) && CanCastCheck("Healing Wave", false), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Healing Wave", UnitHeal, "HealingWaveBaitInterrupt");
                HealingWaveBaitInterruptLast = DateTime.Now + TimeSpan.FromMilliseconds((double) rnd.Next(0x7d0, 0xbb8));
            }));
        }

        private static Composite HealingWaveTopUpRaid()
        {
            return new Decorator(ret => (((THSettings.Instance.HealingWave && Me.CurrentMap.IsRaid) && (UnitHealIsValid && Me.Combat)) && ((UnitHeal.Combat && SpellManager.HasSpell("Healing Wave")) && (Me.CurrentMana > (SpellManager.Spells["Healing Wave"].PowerCost * 4)))) && CanCastCheck("Healing Wave", false), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Healing Wave", UnitHeal, "HealingWaveTopUpRaid");
            }));
        }

        private static double HealWeight(WoWUnit target)
        {
            Func<WoWUnit, bool> predicate = null;
            Func<WoWUnit, bool> func2 = null;
            if (!BasicCheck(target))
            {
                return 1000.0;
            }
            if (!target.Combat)
            {
                return target.HealthPercent;
            }
            int num = 0;
            if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
            {
                if (predicate == null)
                {
                    predicate = unit => ((BasicCheck(unit) && unit.Combat) && unit.GotTarget) && (unit.CurrentTarget == target);
                }
                foreach (WoWUnit unit in FarUnFriendlyPlayers.Where<WoWUnit>(predicate))
                {
                    if ((TalentSort(unit) < 4) && BuffBurst(unit))
                    {
                        num += 5;
                    }
                    else
                    {
                        num += 3;
                    }
                }
            }
            else
            {
                if (func2 == null)
                {
                    func2 = unit => ((BasicCheck(unit) && unit.Combat) && unit.GotTarget) && (unit.CurrentTarget == target);
                }
                foreach (WoWUnit unit2 in FarUnFriendlyUnits.Where<WoWUnit>(func2))
                {
                    if (unit2.IsBoss)
                    {
                        num += 5;
                    }
                    else
                    {
                        num++;
                    }
                }
            }
            return ((target.HealthPercent - num) - THSettings.Instance.HealBalancing);
        }

        private static float HeightOffTheGround(WoWPoint Point, int HoverZ)
        {
            IEnumerable<float> source = from h in Navigator.FindHeights(Point.X, Point.Y)
                where h <= Point.Z
                select h;
            if (source.Any<float>())
            {
                return (Point.Z - source.Max());
            }
            return (float) HoverZ;
        }

        private static Composite Hex()
        {
            return new Decorator(ret => ((THSettings.Instance.Hex && (HealWeightUnitHeal >= THSettings.Instance.PriorityHeal)) && CanCastCheck("Hex", false)) && GetUnitUnitHex(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Hex", UnitHex, "Hex");
            }));
        }

        private static Composite Hold()
        {
            return new Decorator(delegate (object ret) {
                if (((((StyxWoW.IsInWorld && Me.IsValid) && Me.IsAlive) && (THSettings.Instance.AutoAttackOutCombat || Me.Combat)) && (!MeHasAura("Food") || (Me.HealthPercent >= THSettings.Instance.DoNotHealAbove))) && (!MeHasAura("Drink") || ((Me.ManaPercent >= THSettings.Instance.DoNotHealAbove) && (Me.GetAuraByName("Drink").TimeLeft.TotalSeconds <= 9.0))))
                {
                    return MeHasAura("Resurrection Sickness");
                }
                return true;
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                if (Me.IsAutoAttacking)
                {
                    Lua.DoString("RunMacroText('/stopattack');", "WoW.lua");
                }
                Styx.Common.Logging.Write("Hold");
                return RunStatus.Success;
            }));
        }

        private static void HoldBotAction(string spellName)
        {
            if (IsUsingAFKBot)
            {
                new Wait(TimeSpan.FromMilliseconds(3000.0), ret => Me.IsCasting, new ActionAlwaysSucceed());
                while (Me.IsCasting)
                {
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "HoldBotAction Casting " + spellName);
                }
                new WaitContinue(TimeSpan.FromMilliseconds(3000.0), ret => !Me.IsCasting, new ActionAlwaysSucceed());
            }
        }

        private static Composite Hotkey1()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (((((THSettings.Instance.Hotkey1Target != 0) && (THSettings.Instance.Hotkey1Key != 0)) && (THSettings.Instance.Hotkey1Spell != 0)) && ((THSettings.Instance.Hotkey1Mod == 0) || ((THSettings.Instance.Hotkey1Mod != 0) && (GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey1Mod)) < 0)))) && (((GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey1Key)) < 0) && HotKeyTargetValidate(THSettings.Instance.Hotkey1Target)) && HotKeySpellValidate(THSettings.Instance.Hotkey1Spell)))
                {
                    SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey1Target));
                    if (Me.IsCasting && (Me.CastingSpell.Name != HotKeySpelltoName(THSettings.Instance.Hotkey1Spell)))
                    {
                        SpellManager.StopCasting();
                    }
                    CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey1Spell), HotkeyTargettoUnit(THSettings.Instance.Hotkey1Target), "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey1Spell) + " on " + HotkeyTargettoUnit(THSettings.Instance.Hotkey1Target).SafeName);
                    if (GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey1Key)) < 0)
                    {
                        return RunStatus.Success;
                    }
                }
                return RunStatus.Failure;
            });
        }

        private static Composite Hotkey2()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (((((THSettings.Instance.Hotkey2Target != 0) && (THSettings.Instance.Hotkey2Key != 0)) && (THSettings.Instance.Hotkey2Spell != 0)) && ((THSettings.Instance.Hotkey2Mod == 0) || ((THSettings.Instance.Hotkey2Mod != 0) && (GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey2Mod)) < 0)))) && (((GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey2Key)) < 0) && HotKeyTargetValidate(THSettings.Instance.Hotkey2Target)) && HotKeySpellValidate(THSettings.Instance.Hotkey2Spell)))
                {
                    SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey2Target));
                    if (Me.IsCasting && (Me.CastingSpell.Name != HotKeySpelltoName(THSettings.Instance.Hotkey2Spell)))
                    {
                        SpellManager.StopCasting();
                    }
                    CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey2Spell), HotkeyTargettoUnit(THSettings.Instance.Hotkey2Target), "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey2Spell) + " on " + HotkeyTargettoUnit(THSettings.Instance.Hotkey2Target).SafeName);
                    if (GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey2Key)) < 0)
                    {
                        return RunStatus.Success;
                    }
                }
                return RunStatus.Failure;
            });
        }

        private static Composite Hotkey3()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (((((THSettings.Instance.Hotkey3Target != 0) && (THSettings.Instance.Hotkey3Key != 0)) && (THSettings.Instance.Hotkey3Spell != 0)) && ((THSettings.Instance.Hotkey3Mod == 0) || ((THSettings.Instance.Hotkey3Mod != 0) && (GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey3Mod)) < 0)))) && (((GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey3Key)) < 0) && HotKeyTargetValidate(THSettings.Instance.Hotkey3Target)) && HotKeySpellValidate(THSettings.Instance.Hotkey3Spell)))
                {
                    SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey3Target));
                    if (Me.IsCasting && (Me.CastingSpell.Name != HotKeySpelltoName(THSettings.Instance.Hotkey3Spell)))
                    {
                        SpellManager.StopCasting();
                    }
                    CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey3Spell), HotkeyTargettoUnit(THSettings.Instance.Hotkey3Target), "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey3Spell) + " on " + HotkeyTargettoUnit(THSettings.Instance.Hotkey3Target).SafeName);
                    if (GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey3Key)) < 0)
                    {
                        return RunStatus.Success;
                    }
                }
                return RunStatus.Failure;
            });
        }

        private static Composite Hotkey4()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (((((THSettings.Instance.Hotkey4Target != 0) && (THSettings.Instance.Hotkey4Key != 0)) && (THSettings.Instance.Hotkey4Spell != 0)) && ((THSettings.Instance.Hotkey4Mod == 0) || ((THSettings.Instance.Hotkey4Mod != 0) && (GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey4Mod)) < 0)))) && (((GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey4Key)) < 0) && HotKeyTargetValidate(THSettings.Instance.Hotkey4Target)) && HotKeySpellValidate(THSettings.Instance.Hotkey4Spell)))
                {
                    SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey4Target));
                    if (Me.IsCasting && (Me.CastingSpell.Name != HotKeySpelltoName(THSettings.Instance.Hotkey4Spell)))
                    {
                        SpellManager.StopCasting();
                    }
                    CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey4Spell), HotkeyTargettoUnit(THSettings.Instance.Hotkey4Target), "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey4Spell) + " on " + HotkeyTargettoUnit(THSettings.Instance.Hotkey4Target).SafeName);
                    if (GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey4Key)) < 0)
                    {
                        return RunStatus.Success;
                    }
                }
                return RunStatus.Failure;
            });
        }

        private static Composite Hotkey5()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (((((THSettings.Instance.Hotkey5Target != 0) && (THSettings.Instance.Hotkey5Key != 0)) && (THSettings.Instance.Hotkey5Spell != 0)) && ((THSettings.Instance.Hotkey5Mod == 0) || ((THSettings.Instance.Hotkey5Mod != 0) && (GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey5Mod)) < 0)))) && (((GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey5Key)) < 0) && HotKeyTargetValidate(THSettings.Instance.Hotkey5Target)) && HotKeySpellValidate(THSettings.Instance.Hotkey5Spell)))
                {
                    SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey5Target));
                    if (Me.IsCasting && (Me.CastingSpell.Name != HotKeySpelltoName(THSettings.Instance.Hotkey5Spell)))
                    {
                        SpellManager.StopCasting();
                    }
                    CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey5Spell), HotkeyTargettoUnit(THSettings.Instance.Hotkey5Target), "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey5Spell) + " on " + HotkeyTargettoUnit(THSettings.Instance.Hotkey5Target).SafeName);
                    if (GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey5Key)) < 0)
                    {
                        return RunStatus.Success;
                    }
                }
                return RunStatus.Failure;
            });
        }

        private static string HotKeySpelltoName(int HotkeySpell)
        {
            switch (HotkeySpell)
            {
                case 1:
                    return "Ghost Wolf";

                case 2:
                    return "Grounding Totem";

                case 3:
                    return "Hex";

                case 4:
                    return "Purge";

                case 5:
                    return "Tremor Totem";

                case 6:
                    return "Wind Shear";
            }
            return "None Exist Spell";
        }

        private static bool HotKeySpellValidate(int HotkeySpell)
        {
            return true;
        }

        private static WoWUnit HotkeyTargettoUnit(int HotkeyTarget)
        {
            switch (HotkeyTarget)
            {
                case 1:
                    if (!BasicCheck(Me.CurrentTarget))
                    {
                        break;
                    }
                    return Me.CurrentTarget;

                case 2:
                    if (!BasicCheck(Me.FocusedUnit))
                    {
                        break;
                    }
                    return Me.FocusedUnit;

                case 3:
                    return Me;
            }
            return null;
        }

        private static bool HotKeyTargetValidate(int HotkeyTarget)
        {
            return (HotkeyTargettoUnit(HotkeyTarget) != null);
        }

        private static bool IGroupHealingOn()
        {
            if (!SpellManager.HasSpell("Holy Insight"))
            {
                GroupHealingOn = false;
                return false;
            }
            if (((THSettings.Instance.Group1 && THSettings.Instance.Group2) && (THSettings.Instance.Group3 && THSettings.Instance.Group4)) && ((THSettings.Instance.Group5 && THSettings.Instance.Group6) && (THSettings.Instance.Group7 && THSettings.Instance.Group8)))
            {
                GroupHealingOn = false;
                return false;
            }
            if (((!THSettings.Instance.Group1 && !THSettings.Instance.Group2) && (!THSettings.Instance.Group3 && !THSettings.Instance.Group4)) && ((!THSettings.Instance.Group5 && !THSettings.Instance.Group6) && (!THSettings.Instance.Group7 && !THSettings.Instance.Group8)))
            {
                GroupHealingOn = false;
                return false;
            }
            if (!Me.IsInMyRaid)
            {
                GroupHealingOn = false;
                return false;
            }
            if (Me.CurrentMap.IsBattleground)
            {
                GroupHealingOn = false;
                return false;
            }
            Styx.Common.Logging.Write("----------------------------------");
            Styx.Common.Logging.Write("Selective Group Healing Mode On");
            Styx.Common.Logging.Write("----------------------------------");
            GroupHealingOn = true;
            return true;
        }

        private static string ImbuesIdToName(int ImbuesId)
        {
            switch (ImbuesId)
            {
                case 1:
                    return "Windfury Weapon";

                case 2:
                    return "Flametongue Weapon";

                case 3:
                    return "Frostbrand Weapon";

                case 4:
                    return "Rockbiter Weapon";

                case 5:
                    return "Earthliving Weapon";
            }
            return "Invalid Weapon";
        }

        private static int ImbuesIdToTemporaryEnchantmentId(int ImbuesId)
        {
            switch (ImbuesId)
            {
                case 1:
                    return 0x11b;

                case 2:
                    return 5;

                case 3:
                    return 2;

                case 4:
                    return 0xbcd;

                case 5:
                    return 0xd11;
            }
            return 0x4d2;
        }

        private static Keys IndexToKeys(int index)
        {
            switch (index)
            {
                case 1:
                    return Keys.A;

                case 2:
                    return Keys.B;

                case 3:
                    return Keys.C;

                case 4:
                    return Keys.D;

                case 5:
                    return Keys.E;

                case 6:
                    return Keys.F;

                case 7:
                    return Keys.G;

                case 8:
                    return Keys.H;

                case 9:
                    return Keys.I;

                case 10:
                    return Keys.J;

                case 11:
                    return Keys.K;

                case 12:
                    return Keys.L;

                case 13:
                    return Keys.M;

                case 14:
                    return Keys.N;

                case 15:
                    return Keys.O;

                case 0x10:
                    return Keys.P;

                case 0x11:
                    return Keys.Q;

                case 0x12:
                    return Keys.R;

                case 0x13:
                    return Keys.S;

                case 20:
                    return Keys.T;

                case 0x15:
                    return Keys.U;

                case 0x16:
                    return Keys.V;

                case 0x17:
                    return Keys.W;

                case 0x18:
                    return Keys.X;

                case 0x19:
                    return Keys.Y;

                case 0x1a:
                    return Keys.Z;

                case 0x1b:
                    return Keys.D1;

                case 0x1c:
                    return Keys.D2;

                case 0x1d:
                    return Keys.D3;

                case 30:
                    return Keys.D4;

                case 0x1f:
                    return Keys.D5;

                case 0x20:
                    return Keys.D6;

                case 0x21:
                    return Keys.D7;

                case 0x22:
                    return Keys.D8;

                case 0x23:
                    return Keys.D9;

                case 0x24:
                    return Keys.D0;

                case 0x25:
                    return Keys.Up;

                case 0x26:
                    return Keys.Down;

                case 0x27:
                    return Keys.Left;

                case 40:
                    return Keys.Right;

                case 0x29:
                    return Keys.NumPad1;

                case 0x2a:
                    return Keys.NumPad2;

                case 0x2b:
                    return Keys.NumPad3;

                case 0x2c:
                    return Keys.NumPad4;

                case 0x2d:
                    return Keys.NumPad5;

                case 0x2e:
                    return Keys.NumPad6;

                case 0x2f:
                    return Keys.NumPad7;

                case 0x30:
                    return Keys.NumPad8;

                case 0x31:
                    return Keys.NumPad9;

                case 50:
                    return Keys.NumPad0;
            }
            return Keys.None;
        }

        internal static Keys IndexToKeysMod(int index)
        {
            switch (index)
            {
                case 1:
                    return Keys.LShiftKey;

                case 2:
                    return Keys.LControlKey;

                case 3:
                    return Keys.LMenu;
            }
            return Keys.None;
        }

        public override void Initialize()
        {
            Styx.Common.Logging.Write("");
            Styx.Common.Logging.Write(string.Concat(new object[] { "Hello level ", Me.Level, " ", Me.Race, " ", Me.Class }));
            Styx.Common.Logging.Write("");
            Styx.Common.Logging.Write("Thank you for using TuanHA Shaman Special Edition");
            Styx.Common.Logging.Write("");
            Styx.Common.Logging.Write("For best Combat Routine performance, please set Custom Lag Tolerance to 400 ms.");
            Styx.Common.Logging.Write("Game Menu > Interface > Combat Check Custom Lag Toerance and Adjust the Slider to 400 ms");
            Styx.Common.Logging.Write("Best Non-AFK Botbase are LazyRaider: http://goo.gl/nf0zab or Tyrael http://goo.gl/51E0F6");
            Styx.Common.Logging.Write("For detailed installation guide, visit our new website");
            Styx.Common.Logging.Write("www.tuanha.biz");
            Styx.Common.Logging.Write("");
            Lua.Events.AttachEvent("GROUP_ROSTER_UPDATE", new LuaEventHandlerDelegate(Classname.UpdateGroupChangeEvent));
            Lua.Events.AttachEvent("ACTIVE_TALENT_GROUP_CHANGED", new LuaEventHandlerDelegate(Classname.UpdateStatusEvent));
            Lua.Events.AttachEvent("GLYPH_ADDED", new LuaEventHandlerDelegate(Classname.UpdateMyGlyphEvent));
            Lua.Events.AttachEvent("GLYPH_ADDED", new LuaEventHandlerDelegate(Classname.UpdateMyGlyphEvent));
            Lua.Events.AttachEvent("GLYPH_UPDATED", new LuaEventHandlerDelegate(Classname.UpdateMyGlyphEvent));
            Lua.Events.AttachEvent("GLYPH_REMOVED", new LuaEventHandlerDelegate(Classname.UpdateMyGlyphEvent));
            Chat.NeutralBattleground += new Chat.ChatMessageHandlerEx<Chat.ChatSimpleMessageEventArgs>(Classname.ChatFilter);
            Chat.AllianceBattleground += new Chat.ChatMessageHandlerEx<Chat.ChatSimpleMessageEventArgs>(Classname.ChatFilter);
            Chat.HordeBattleground += new Chat.ChatMessageHandlerEx<Chat.ChatSimpleMessageEventArgs>(Classname.ChatFilter);
            BotEvents.OnBotStarted += new BotEvents.OnBotStartDelegate(Classname.OnBotStartedEvent);
            this.PreBuffSelector();
            this.RotationSelector();
            this.RestSelector();
            this.DeathSelector();
            THSettings.Instance.UpdateStatus = true;
            if (!LoginCheckVal)
            {
                Styx.Common.Logging.Write("Please Log In.");
                this.OnButtonPress();
            }
        }

        private static void InLineOfSpellSightCacheAdd(WoWUnit unit, int expireMilliseconds = 100)
        {
            if (!InLineOfSpellSightCache.ContainsKey(unit.Guid))
            {
                InLineOfSpellSightCache.Add(unit.Guid, DateTime.Now + TimeSpan.FromMilliseconds((double) expireMilliseconds));
            }
        }

        private static void InLineOfSpellSightCacheClear()
        {
            foreach (ulong num in (from unit in InLineOfSpellSightCache
                where unit.Value < DateTime.Now
                select unit.Key).ToList<ulong>())
            {
                InLineOfSpellSightCache.Remove(num);
            }
        }

        private static bool InLineOfSpellSightCheck(WoWUnit target)
        {
            if (!BasicCheck(target))
            {
                return false;
            }
            InLineOfSpellSightCacheClear();
            if ((target != Me) && !InLineOfSpellSightCache.ContainsKey(target.Guid))
            {
                if (!target.InLineOfSpellSight)
                {
                    return false;
                }
                if (Me.CurrentMap.IsRaid || Me.CurrentMap.IsDungeon)
                {
                    InLineOfSpellSightCacheAdd(target, 300);
                    return true;
                }
                InLineOfSpellSightCacheAdd(target, 100);
            }
            return true;
        }

        private static bool InterruptCheck(WoWUnit unit, double millisecondsleft, bool includeUninterruptable = true)
        {
            return ((((((unit != null) && unit.IsValid) && ((Me.CurrentMap.Name == "Proving Grounds") || unit.Combat)) && (unit.IsCasting || unit.IsChanneling)) && ((includeUninterruptable || unit.CanInterruptCurrentSpellCast) && (!unit.IsCasting || !DoNotInterrupt.Contains(unit.CastingSpellId)))) && ((!unit.IsChanneling || !DoNotInterrupt.Contains(unit.ChanneledCastingSpellId)) && (!unit.IsCasting || (unit.CurrentCastTimeLeft.TotalMilliseconds <= (millisecondsleft + MyLatency)))));
        }

        private static bool InterruptCheckGrounding(WoWUnit unit, double millisecondsleft)
        {
            return ((((((unit != null) && unit.IsValid) && (unit.Combat && unit.IsCasting)) && (!unit.IsCasting || GroundingHS.Contains(unit.CastingSpellId))) && (!unit.IsChanneling || GroundingHS.Contains(unit.ChanneledCastingSpellId))) && (!unit.IsCasting || (unit.CurrentCastTimeLeft.TotalMilliseconds <= (millisecondsleft + MyLatency))));
        }

        private static void InterruptonCooldownUnitAdd(WoWUnit unit, int expireSeconds)
        {
            ulong unitGUID = unit.Guid;
            foreach (ulong num in (from u in InterruptonCooldownUnitList
                where u.Key == unitGUID
                select u.Key).ToList<ulong>())
            {
                InterruptonCooldownUnitList.Remove(num);
            }
            InterruptonCooldownUnitList.Add(unitGUID, DateTime.Now + TimeSpan.FromSeconds((double) expireSeconds));
        }

        private static void InterruptonCooldownUnitListClear()
        {
            foreach (ulong num in (from unit in InterruptonCooldownUnitList
                where unit.Value < DateTime.Now
                select unit.Key).ToList<ulong>())
            {
                InterruptonCooldownUnitList.Remove(num);
            }
        }

        private static int InterruptSpellCooldown(int spellID)
        {
            switch (spellID)
            {
                case 0x4cbf:
                    return 0x5dc0;

                case 0x86ba:
                    return 0x5dc0;

                case 0x85b:
                    return 0x55f0;

                case 0x3c7f:
                    return 0xafc8;

                case 0xb974:
                    return 0xea60;

                case 0x1961f:
                    return 0x2ee0;

                case 0x1c445:
                    return 0x5dc0;

                case 0x23fa2:
                    return 0x5dc0;
            }
            return 0x3a98;
        }

        private static bool Invulnerable(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => InvulnerableHS.Contains(aura.SpellId));
        }

        private static bool InvulnerablePhysic(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return UnitHasAura(0x3fe, target);
        }

        private static bool InvulnerableRootandSnare(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => InvulnerableRootandSnareHS.Contains(aura.SpellId));
        }

        private static bool InvulnerableSpell(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return target.GetAllAuras().Any<WoWAura>(aura => InvulnerableSpellHS.Contains(aura.SpellId));
        }

        private static bool InvulnerableStun(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return (((target.Class == WoWClass.Monk) && (TalentSort(target) > 3)) || target.GetAllAuras().Any<WoWAura>(aura => InvulnerableStunHS.Contains(aura.SpellId)));
        }

        private static bool IsCastingCCGhostWolfImmune(WoWUnit unit)
        {
            return (((unit != null) && unit.IsValid) && (unit.IsCasting && (!unit.IsCasting || GhostWolfHS.Contains(unit.CastingSpellId))));
        }

        private static bool IsDummy(WoWUnit target)
        {
            if (((((target.Entry != 0x79aa) && (target.Entry != 0x10637)) && ((target.Entry != 0xb637) && (target.Entry != 0x7f22))) && (((target.Entry != 0x79a8) && (target.Entry != 0x7f1f)) && ((target.Entry != 0x7f9b) && (target.Entry != 0x7f1e)))) && (target.Entry != 0x7f9a))
            {
                return (target.Entry == 0x773f);
            }
            return true;
        }

        private static bool IsEnemy(WoWUnit target)
        {
            if (EnemyListCache.ContainsKey(target.Guid))
            {
                return true;
            }
            if (!FriendListCache.ContainsKey(target.Guid))
            {
                if (IsMyPartyRaidMember(target))
                {
                    if (UnitHasAura("Reshape Life", target) || UnitHasAura("Convert", target))
                    {
                        return true;
                    }
                    FriendListCacheAdd(target, 60);
                    return false;
                }
                if (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)
                {
                    EnemyListCacheAdd(target, 10);
                    return true;
                }
                if ((!target.IsFriendly && target.Attackable) && !target.IsQuestGiver)
                {
                    EnemyListCacheAdd(target, 10);
                    return true;
                }
                if ((Me.Combat && IsDummy(target)) && Me.IsFacing(target))
                {
                    EnemyListCacheAdd(target, 10);
                    return true;
                }
            }
            return false;
        }

        private static bool IsFriendlyHunterNearby()
        {
            return FarUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(player => (BasicCheck(player) && (player.Class == WoWClass.Hunter)));
        }

        private static bool IsHealing()
        {
            if (!Me.IsCasting)
            {
                return false;
            }
            if ((!(Me.CastingSpell.Name == "Flash of Light") && !(Me.CastingSpell.Name == "Divine Light")) && !(Me.CastingSpell.Name == "Holy Light"))
            {
                return (Me.CastingSpell.Name == "Holy Radiance");
            }
            return true;
        }

        private static bool IsMoving(WoWUnit target)
        {
            if ((!target.MovementInfo.MovingBackward && !target.MovementInfo.MovingForward) && !target.MovementInfo.MovingStrafeLeft)
            {
                return target.MovementInfo.MovingStrafeRight;
            }
            return true;
        }

        private static bool IsMyPartyRaidMember(WoWUnit target)
        {
            if (FriendListCache.ContainsKey(target.Guid))
            {
                return true;
            }
            if (!EnemyListCache.ContainsKey(target.Guid))
            {
                if (NeedHealUnit(target))
                {
                    FriendListCacheAdd(target, 60);
                    return true;
                }
                if (target.IsPlayer)
                {
                    WoWPlayer player = target as WoWPlayer;
                    if ((player != null) && ((player == Me) || player.IsInMyPartyOrRaid))
                    {
                        FriendListCacheAdd(target, 60);
                        return true;
                    }
                }
                else
                {
                    WoWPlayer createdByUnit = target.CreatedByUnit as WoWPlayer;
                    if ((createdByUnit != null) && ((createdByUnit == Me) || createdByUnit.IsInMyPartyOrRaid))
                    {
                        FriendListCacheAdd(target, 60);
                        return true;
                    }
                }
            }
            return false;
        }

        private static bool IsSafetoCast()
        {
            if (MeHasAura("Spiritwalker's Aegis") || MeHasAura("Devotion Aura"))
            {
                return true;
            }
            InterruptonCooldownUnitListClear();
            return NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(unit => InterruptonCooldownUnitList.ContainsKey(unit.Guid));
        }

        private static bool IsTank(WoWUnit target)
        {
            if (target.Entry != 0x11a1a)
            {
                return UnitHasAura("Vengeance", target);
            }
            return true;
        }

        private static bool IsWorthyTarget(WoWUnit target, double pvEPercent = 1.0, double pvPPercent = 0.3)
        {
            if (Me.HealthPercent < 20.0)
            {
                return false;
            }
            if ((!IsDummy(target) && (target.IsPet || (target.CurrentHealth <= (Me.CurrentHealth * pvEPercent)))) && (!target.IsPlayer || (target.CurrentHealth <= (Me.CurrentHealth * pvPPercent))))
            {
                return false;
            }
            return true;
        }

        private static void ItemsCooldownCacheAdd(WoWItem Item, DateTime CooldownBack)
        {
            ItemsCooldownCache.Add(Item, CooldownBack);
        }

        private static void ItemsCooldownCacheClear()
        {
            foreach (WoWItem item in (from unit in ItemsCooldownCache
                where unit.Value <= DateTime.Now
                select unit.Key).ToList<WoWItem>())
            {
                ItemsCooldownCache.Remove(item);
            }
        }

        private static Composite LavaBustElemental()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.LavaBustElemental || !CurrentTargetAttackable(40.0, false, false)) || (CurrentTargetCheckInvulnerableMagic || !FacingOverride(Me.CurrentTarget))) || (!MyAura("Flame Shock", Me.CurrentTarget) && CanCastCheck("Flame Shock", false)))
                {
                    return false;
                }
                return CanCastCheck("Lava Burst", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lava Burst", Me.CurrentTarget, "LavaBustElemental");
            }));
        }

        private static Composite LavaBustElementalProc()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.LavaBustElemental || !CurrentTargetAttackable(40.0, false, false)) || (CurrentTargetCheckInvulnerableMagic || !FacingOverride(Me.CurrentTarget))) || (!MeHasAura(0x12fc2) || (!MyAura("Flame Shock", Me.CurrentTarget) && CanCastCheck("Flame Shock", false))))
                {
                    return false;
                }
                return CanCastCheck("Lava Burst", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lava Burst", Me.CurrentTarget, "LavaBustElementalProc");
            }));
        }

        private static Composite LavaLash()
        {
            return new Decorator(ret => ((THSettings.Instance.LavaLash && CurrentTargetAttackable(5.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget))) && CanCastCheck("Lava Lash", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lava Lash", Me.CurrentTarget, "LavaLash");
            }));
        }

        private static Composite LightningBoltAncestralSwiftness()
        {
            return new Decorator(ret => ((((THSettings.Instance.LightningBolt && THSettings.Instance.AncestralSwiftnessLB) && (CurrentTargetAttackable(30.0, false, false) && !CurrentTargetCheckInvulnerableMagic)) && ((MyAuraStackCount(0xd239, Me) <= 0.0) && (IsWorthyTarget(Me.CurrentTarget, 2.0, 0.5) || HaveWorthyTargetAttackingMe()))) && (FacingOverride(Me.CurrentTarget) && CanCastCheck("Ancestral Swiftness", false))) && CanCastCheck("Lightning Bolt", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Ancestral Swiftness", Me.CurrentTarget, "AncestralSwiftnessLightningBolt");
                CastSpell("Lightning Bolt", Me.CurrentTarget, "LightningBoltAncestralSwiftness");
            }));
        }

        private static Composite LightningBoltEnh()
        {
            return new Decorator(ret => (((THSettings.Instance.LightningBoltEnh && CurrentTargetAttackable(30.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && (MyAuraStackCount(0xd239, Me) >= THSettings.Instance.LightningBoltEnhMaelstromStack))) && FacingOverride(Me.CurrentTarget)) && CanCastCheck("Lightning Bolt", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lightning Bolt", Me.CurrentTarget, "LightningBoltEnh");
            }));
        }

        private static Composite LightningBoltFillerElemental()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.LightningBoltFillerElemental || !CurrentTargetAttackable((double) ((int) SpellManager.Spells["Lightning Bolt"].MaxRange), false, false)) || (CurrentTargetCheckInvulnerableMagic || Me.IsCasting)) || (!FacingOverride(Me.CurrentTarget) || !CanCastCheck("Lightning Bolt", false)))
                {
                    return false;
                }
                if (SpellManager.HasSpell("Flame Shock"))
                {
                    return MyAuraTimeLeft("Flame Shock", Me.CurrentTarget) > 2000.0;
                }
                return true;
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lightning Bolt", Me.CurrentTarget, "LightningBoltFillerElemental");
            }));
        }

        private static Composite LightningBoltFillerElementalAoE()
        {
            return new Decorator(ret => (((THSettings.Instance.LightningBoltFillerElemental && CurrentTargetAttackable((double) ((int) SpellManager.Spells["Lightning Bolt"].MaxRange), false, false)) && (!CurrentTargetCheckInvulnerableMagic && !Me.IsCasting)) && (FacingOverride(Me.CurrentTarget) && !MeHasAura(0x12fc2))) && CanCastCheck("Lightning Bolt", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lightning Bolt", Me.CurrentTarget, "LightningBoltFillerElementalAoE");
            }));
        }

        private static Composite LightningBoltFillerEnh()
        {
            return new Decorator(delegate (object ret) {
                if ((((!THSettings.Instance.LightningBoltFiller || (LastLightningBoltFiller >= DateTime.Now)) || (!CurrentTargetAttackable(30.0, false, false) || CurrentTargetCheckInvulnerableMagic)) || ((Me.IsCasting || !FacingOverride(Me.CurrentTarget)) || (!SpellManager.HasSpell("Lightning Bolt") || (Me.CurrentMana <= (SpellManager.Spells["Lightning Bolt"].PowerCost * 3))))) || ((MyAuraStackCount(0xd239, Me) < THSettings.Instance.LightningBoltFillerMaelstromStack) && SpellManager.HasSpell("Maelstrom Weapon")))
                {
                    return false;
                }
                return CanCastCheck("Lightning Bolt", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                LastLightningBoltFiller = DateTime.Now + TimeSpan.FromSeconds(3.0);
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lightning Bolt", Me.CurrentTarget, "LightningBoltFiller");
            }));
        }

        private static Composite LightningBoltFillerEnhRange()
        {
            return new Decorator(ret => ((THSettings.Instance.LightningBolt && (Me.CurrentMap.IsBattleground || Me.CurrentMap.IsArena)) && (((CurrentTargetAttackable(30.0, false, false) && !CurrentTargetAttackable(7.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget))) && ((SpellManager.HasSpell("Lightning Bolt") && (Me.CurrentMana > (SpellManager.Spells["Lightning Bolt"].PowerCost * 3))) && CanCastCheck("Lightning Bolt", false)))) && (!MeHasAura(0xd239) || ((MyAuraStackCount(0xd239, Me) < 2.0) && DebuffRoot(Me))), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Lightning Bolt", Me.CurrentTarget, "LightningBoltFillerEnhRange");
            }));
        }

        private static Composite LightningBoltTelluricCurrents()
        {
            return new Decorator(ret => ((((THSettings.Instance.AttackRestoLightningBoltGlyph && HasGlyph.Contains("55453")) && (Me.Combat && !Me.IsCasting)) && ((Me.ManaPercent < THSettings.Instance.DoNotHealAbove) && ((Me.ManaPercent < 20.0) || (HealWeightUnitHeal > 90.0)))) && CanCastCheck("Lightning Bolt", false)) && GetUnitAttackRTelluricCurrents(), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(UnitAttackRTelluricCurrents);
                CastSpell("Lightning Bolt", UnitAttackRTelluricCurrents, "AttackRestoLightningBoltGlyph");
            }));
        }

        private static Composite LightningShield()
        {
            return new Decorator(ret => (THSettings.Instance.LightningShield && (MyAuraTimeLeft(0x144, Me) < 1800000.0)) && CanCastCheck("Lightning Shield", false), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Lightning Shield", Me, "LightningShield");
            }));
        }

        private static Composite LoginCheck()
        {
            return new Decorator(ret => !LoginCheckVal, new Styx.TreeSharp.Action(delegate (object param0) {
                Styx.Common.Logging.Write("Please Click Class Config to Login.");
                return RunStatus.Success;
            }));
        }

        private static Composite MagmaTotemEle()
        {
            return new Decorator(ret => ((THSettings.Instance.MagmaTotemEle && !MyTotemCheck("Fire Elemental Totem", Me, 40)) && (!MyTotemCheck("Magma Totem", Me, 40) && CanCastCheck("Magma Totem", false))) && (CountEnemyNear(Me, 8f) >= THSettings.Instance.MagmaTotemEleUnit), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Magma Totem", Me, "MagmaTotemEle");
            }));
        }

        private static Composite MagmaTotemEnh()
        {
            return new Decorator(ret => ((THSettings.Instance.MagmaTotemEnh && !MyTotemCheck("Fire Elemental Totem", Me, 40)) && (!MyTotemCheck("Magma Totem", Me, 40) && CanCastCheck("Magma Totem", true))) && (CountEnemyNear(Me, 10f) >= THSettings.Instance.MagmaTotemEnhUnit), new Styx.TreeSharp.Action(delegate (object param0) {
                SpellManager.StopCasting();
                CastSpell("Magma Totem", Me, "MagmaTotemEnh");
            }));
        }

        private static Composite MainRotation()
        {
            return new PrioritySelector(new Composite[] { 
                LoginCheck(), new Styx.TreeSharp.Action(delegate (object param0) {
                    if ((LastWriteDebug < DateTime.Now) && (GetAsyncKeyState(Keys.F10) != 0))
                    {
                        LastWriteDebug = DateTime.Now + TimeSpan.FromSeconds(5.0);
                        Styx.Common.Logging.Write("=============================");
                        Styx.Common.Logging.Write("SpellsCooldownCache");
                        object[] args = new object[] { (DateTime.Now + SpellManager.GlobalCooldownLeft).ToString("ss:fff"), DateTime.Now.ToString("ss:fff") };
                        Styx.Common.Logging.Write("{1} GCDBack {0}", args);
                        foreach (KeyValuePair<string, DateTime> pair in SpellsCooldownCache)
                        {
                            Styx.Common.Logging.Write("{2}: {0} - {1}", new object[] { pair.Key, pair.Value.ToString("ss:fff"), DateTime.Now.ToString("ss:fff") });
                        }
                        Styx.Common.Logging.Write("=============================");
                    }
                    if (GetAsyncKeyState(Keys.F9) != 0)
                    {
                        Styx.Common.Logging.Write("=============================");
                        object[] objArray3 = new object[1];
                        TimeSpan span = (TimeSpan) (DateTime.Now - LastRotationTime);
                        objArray3[0] = span.TotalMilliseconds;
                        Styx.Common.Logging.Write("LastRotationTime take {0} ms", objArray3);
                        LastRotationTime = DateTime.Now;
                        Styx.Common.Logging.Write("=============================");
                    }
                    if ((LastWriteDebug < DateTime.Now) && (GetAsyncKeyState(Keys.F8) != 0))
                    {
                        LastWriteDebug = DateTime.Now + TimeSpan.FromSeconds(5.0);
                        int num = 1;
                        Styx.Common.Logging.Write("=============================");
                        num = 1;
                        Styx.Common.Logging.Write("NearbyFriendlyPlayers");
                        foreach (WoWUnit unit in NearbyFriendlyPlayers)
                        {
                            Styx.Common.Logging.Write(num + ". " + unit.SafeName);
                            num++;
                        }
                        Styx.Common.Logging.Write("=============================");
                        num = 1;
                        Styx.Common.Logging.Write("NearbyFriendlyUnits");
                        foreach (WoWUnit unit2 in NearbyFriendlyUnits)
                        {
                            Styx.Common.Logging.Write(num + ". " + unit2.SafeName);
                            num++;
                        }
                        Styx.Common.Logging.Write("=============================");
                        num = 1;
                        Styx.Common.Logging.Write("FarFriendlyPlayers");
                        foreach (WoWUnit unit3 in FarFriendlyPlayers)
                        {
                            Styx.Common.Logging.Write(num + ". " + unit3.SafeName);
                            num++;
                        }
                        Styx.Common.Logging.Write("=============================");
                        num = 1;
                        Styx.Common.Logging.Write("FarFriendlyUnits");
                        foreach (WoWUnit unit4 in FarFriendlyUnits)
                        {
                            Styx.Common.Logging.Write(num + ". " + unit4.SafeName);
                            num++;
                        }
                        Styx.Common.Logging.Write("=============================");
                        num = 1;
                        Styx.Common.Logging.Write("NearbyUnFriendlyPlayers");
                        foreach (WoWUnit unit5 in NearbyUnFriendlyPlayers)
                        {
                            Styx.Common.Logging.Write(num + ". " + unit5.SafeName);
                            num++;
                        }
                        Styx.Common.Logging.Write("=============================");
                        num = 1;
                        Styx.Common.Logging.Write("NearbyUnFriendlyUnits");
                        foreach (WoWUnit unit6 in NearbyUnFriendlyUnits)
                        {
                            Styx.Common.Logging.Write(num + ". " + unit6.SafeName);
                            num++;
                        }
                        Styx.Common.Logging.Write("=============================");
                        num = 1;
                        Styx.Common.Logging.Write("FarUnFriendlyPlayers");
                        foreach (WoWUnit unit7 in FarUnFriendlyPlayers)
                        {
                            Styx.Common.Logging.Write(num + ". " + unit7.SafeName);
                            num++;
                        }
                        Styx.Common.Logging.Write("=============================");
                        num = 1;
                        Styx.Common.Logging.Write("FarUnFriendlyUnits");
                        foreach (WoWUnit unit8 in FarUnFriendlyUnits)
                        {
                            Styx.Common.Logging.Write(num + ". " + unit8.SafeName);
                            num++;
                        }
                    }
                    if ((LastWriteDebug < DateTime.Now) && (GetAsyncKeyState(Keys.F7) != 0))
                    {
                        LastWriteDebug = DateTime.Now + TimeSpan.FromSeconds(5.0);
                        Styx.Common.Logging.Write("=============================");
                        foreach (WoWAura aura in Me.GetAllAuras())
                        {
                            Styx.Common.Logging.Write("{0} {1}", new object[] { aura.Name, aura.SpellId });
                        }
                        Styx.Common.Logging.Write("=============================");
                        if (BasicCheck(Me.CurrentTarget))
                        {
                            Styx.Common.Logging.Write("Me.CurrentTarget.GetAllAuras()");
                            foreach (WoWAura aura2 in Me.CurrentTarget.GetAllAuras())
                            {
                                Styx.Common.Logging.Write("{0} {1}", new object[] { aura2.Name, aura2.SpellId });
                            }
                            Styx.Common.Logging.Write("=============================");
                        }
                    }
                    return RunStatus.Failure;
                }), Hold(), Hotkey1(), Hotkey2(), Hotkey3(), Hotkey4(), Hotkey5(), ManualCastPause(), new Decorator(ret => THSettings.Instance.Pause, new Styx.TreeSharp.Action(param0 => RunStatus.Success)), new Decorator(ret => THSettings.Instance.UpdateStatus, new Styx.TreeSharp.Action(param0 => RunStatus.Success)), GetUnits(), GetUnitHeal(), new Styx.TreeSharp.Action(delegate (object param0) {
                    if (((((!IsOverrideModeOn && (GetAsyncKeyState(Keys.LButton) < 0)) && (GetAsyncKeyState(Keys.RButton) < 0)) || ((GetAsyncKeyState(IndexToKeys(THSettings.Instance.StrafleLeft)) < 0) && (IndexToKeys(THSettings.Instance.StrafleLeft) != Keys.None))) || (((GetAsyncKeyState(IndexToKeys(THSettings.Instance.Forward)) < 0) && (IndexToKeys(THSettings.Instance.Forward) != Keys.None)) || ((GetAsyncKeyState(IndexToKeys(THSettings.Instance.StrafleRight)) < 0) && (IndexToKeys(THSettings.Instance.StrafleRight) != Keys.None)))) || ((((GetAsyncKeyState(IndexToKeys(THSettings.Instance.TurnLeft)) < 0) && (IndexToKeys(THSettings.Instance.TurnLeft) != Keys.None)) || ((GetAsyncKeyState(IndexToKeys(THSettings.Instance.Backward)) < 0) && (IndexToKeys(THSettings.Instance.Backward) != Keys.None))) || ((GetAsyncKeyState(IndexToKeys(THSettings.Instance.TurnRight)) < 0) && (IndexToKeys(THSettings.Instance.TurnRight) != Keys.None))))
                    {
                        IsOverrideModeOn = true;
                    }
                    if ((IsOverrideModeOn && ((GetAsyncKeyState(Keys.LButton) >= 0) || (GetAsyncKeyState(Keys.RButton) >= 0))) && ((((GetAsyncKeyState(IndexToKeys(THSettings.Instance.StrafleLeft)) >= 0) && (GetAsyncKeyState(IndexToKeys(THSettings.Instance.Forward)) >= 0)) && ((GetAsyncKeyState(IndexToKeys(THSettings.Instance.StrafleRight)) >= 0) && (GetAsyncKeyState(IndexToKeys(THSettings.Instance.TurnLeft)) >= 0))) && ((GetAsyncKeyState(IndexToKeys(THSettings.Instance.Backward)) >= 0) && (GetAsyncKeyState(IndexToKeys(THSettings.Instance.TurnRight)) >= 0))))
                    {
                        IsOverrideModeOn = false;
                    }
                    if (((Me.CurrentTarget != null) && Me.CurrentTarget.IsValid) && (MyLastTarget != Me.CurrentTarget))
                    {
                        MyLastTarget = Me.CurrentTarget;
                    }
                    return RunStatus.Failure;
                }), new Styx.TreeSharp.Action(delegate (object param0) {
                    CurrentTargetCheck();
                    return RunStatus.Failure;
                }), UseRacial(), 
                UseProfession(), UseHealthStoneHP(), UseBattleStandard(), AutoSetFocus(), new Decorator(ret => (UseSpecialization == 1) && !Me.Mounted, ElementalRotation()), new Decorator(ret => (UseSpecialization == 2) && !Me.Mounted, EnhancementRotation()), new Decorator(ret => (UseSpecialization == 3) && !Me.Mounted, RestorationRotation()), Dismount()
             });
        }

        private static Composite ManaTideTotem()
        {
            return new Decorator(ret => (((THSettings.Instance.ManaTideTotem && Me.Combat) && ((Me.ManaPercent <= THSettings.Instance.ManaTideTotemMN) && !MyTotemWaterCheck(Me, 40))) && !MeHasAura("Mana Tide")) && CanCastCheck("Mana Tide Totem", false), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Mana Tide Totem", Me, "ManaTideTotem");
            }));
        }

        private static Composite ManualCastPause()
        {
            return new Sequence(new Composite[] { new Decorator(ret => THSettings.Instance.AutoDetectManualCast && AnyKeyPressed(), new ActionAlwaysSucceed()), new Styx.TreeSharp.Action(delegate (object param0) {
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, Colors.Gray, "{0} Manual Cast Detected, Pause for {1} ms", new object[] { DateTime.Now.ToString("ss:fff"), THSettings.Instance.AutoDetectManualCastMS });
            }), new WaitContinue(TimeSpan.FromMilliseconds((double) THSettings.Instance.AutoDetectManualCastMS), ret => false, new ActionAlwaysSucceed()) });
        }

        private static bool MeHasAura(int auraID)
        {
            return Me.GetAllAuras().Any<WoWAura>(aura => (aura.SpellId == auraID));
        }

        private static bool MeHasAura(string auraName)
        {
            return Me.GetAllAuras().Any<WoWAura>(aura => (aura.Name == auraName));
        }

        public Composite MovementMoveBehind(UnitSelectionDelegate toUnit)
        {
            return new Decorator(delegate (object ret) {
                if ((((!THSettings.Instance.AutoMove || (DateTime.Now <= DoNotMove)) || (Me.Mounted || IsOverrideModeOn)) || ((Me.IsCasting || (toUnit == null)) || ((toUnit(ret) == null) || (toUnit(ret) == Me)))) || ((!toUnit(ret).IsAlive || (GetDistance(toUnit(ret)) > 5f)) || Me.IsBehind(toUnit(ret))))
                {
                    return false;
                }
                return toUnit(ret).IsPlayer || ((!toUnit(ret).IsPlayer && (toUnit(ret).CurrentTarget != Me)) && toUnit(ret).Combat);
            }, new Styx.TreeSharp.Action(delegate (object ret) {
                Navigator.MoveTo(toUnit(ret).Location.RayCast(toUnit(ret).Rotation + WoWMathHelper.DegreesToRadians(150f), 3f));
                return RunStatus.Failure;
            }));
        }

        private static Composite MovementMoveStop(UnitSelectionDelegate toUnit, double range)
        {
            return new Decorator(ret => ((((THSettings.Instance.AutoMove && !IsOverrideModeOn) && ((toUnit != null) && (toUnit(ret) != null))) && (((toUnit(ret) != Me) && toUnit(ret).IsAlive) && (IsMoving(Me) && IsEnemy(toUnit(ret))))) && (GetDistance(toUnit(ret)) <= range)) && InLineOfSpellSightCheck(toUnit(ret)), new Styx.TreeSharp.Action(delegate (object ret) {
                Navigator.PlayerMover.MoveStop();
                return RunStatus.Failure;
            }));
        }

        private static Composite MovementMoveToLoS(UnitSelectionDelegate toUnit)
        {
            return new Decorator(delegate (object ret) {
                if ((((!THSettings.Instance.AutoMove || (DateTime.Now <= DoNotMove)) || (Me.Mounted || IsOverrideModeOn)) || ((Me.IsCasting || (toUnit == null)) || ((toUnit(ret) == null) || (toUnit(ret) == Me)))) || (!toUnit(ret).IsAlive || !IsEnemy(toUnit(ret))))
                {
                    return false;
                }
                if (GetDistance(toUnit(ret)) <= 30f)
                {
                    return !InLineOfSpellSightCheck(toUnit(ret));
                }
                return true;
            }, new Styx.TreeSharp.Action(delegate (object ret) {
                Navigator.MoveTo(toUnit(ret).Location);
                return RunStatus.Failure;
            }));
        }

        private static Composite MovementMoveToMelee(UnitSelectionDelegate toUnit)
        {
            return new Decorator(ret => ((((THSettings.Instance.AutoMove && (DateTime.Now > DoNotMove)) && (!Me.Mounted && !IsOverrideModeOn)) && ((!Me.IsCasting && (toUnit != null)) && ((toUnit(ret) != null) && (toUnit(ret) != Me)))) && (toUnit(ret).IsAlive && IsEnemy(toUnit(ret)))) && (GetDistance(toUnit(ret)) > 3f), new Styx.TreeSharp.Action(delegate (object ret) {
                Navigator.MoveTo(toUnit(ret).Location);
                return RunStatus.Failure;
            }));
        }

        private static bool MyAura(int auraID, WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => ((aura.SpellId == auraID) && (aura.CreatorGuid == Me.Guid)));
        }

        private static bool MyAura(string auraName, WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => ((aura.Name == auraName) && (aura.CreatorGuid == Me.Guid)));
        }

        private static double MyAuraStackCount(int auraID, WoWUnit target)
        {
            return (double) (from aura in target.GetAllAuras()
                where (aura.SpellId == auraID) && (aura.CreatorGuid == Me.Guid)
                select aura.StackCount).FirstOrDefault<uint>();
        }

        private static double MyAuraStackCount(string auraName, WoWUnit target)
        {
            return (double) (from aura in target.GetAllAuras()
                where (aura.Name == auraName) && (aura.CreatorGuid == Me.Guid)
                select aura.StackCount).FirstOrDefault<uint>();
        }

        private static double MyAuraTimeLeft(int auraID, WoWUnit target)
        {
            return (from aura in target.GetAllAuras()
                where (aura.SpellId == auraID) && (aura.CreatorGuid == Me.Guid)
                select aura.TimeLeft.TotalMilliseconds).FirstOrDefault<double>();
        }

        private static double MyAuraTimeLeft(string auraName, WoWUnit target)
        {
            return (from aura in target.GetAllAuras()
                where (aura.Name == auraName) && (aura.CreatorGuid == Me.Guid)
                select aura.TimeLeft.TotalMilliseconds).FirstOrDefault<double>();
        }

        private static bool MyTotemAirCheck(WoWUnit target, int distance)
        {
            return (((Me.Totems[3].Unit != null) && (Me.Totems[3].Unit.Name != "Air Totem")) && (GetDistance(Me.Totems[3].Unit, target) <= distance));
        }

        private static bool MyTotemCheck(string totemName, WoWUnit target, int distance)
        {
            for (int i = 0; i < 4; i++)
            {
                if (((Me.Totems[i].Unit != null) && (Me.Totems[i].Unit.Entry == TotemNametoEntry(totemName))) && (GetDistance(Me.Totems[i].Unit, target) <= distance))
                {
                    return true;
                }
            }
            return false;
        }

        private static bool MyTotemCheckExpires(string totemName, int totalMilliseconds)
        {
            for (int i = 0; i < 4; i++)
            {
                if ((Me.Totems[i].Unit != null) && (Me.Totems[i].Unit.Entry == TotemNametoEntry(totemName)))
                {
                    TimeSpan span = (TimeSpan) (Me.Totems[i].Expires - DateTime.Now);
                    if (span.TotalMilliseconds <= totalMilliseconds)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private static bool MyTotemEarthCheck(WoWUnit target, int distance)
        {
            return (((Me.Totems[1].Unit != null) && (Me.Totems[1].Unit.Name != "Earth Totem")) && (GetDistance(Me.Totems[1].Unit, target) <= distance));
        }

        private static bool MyTotemFireCheck(WoWUnit target, int distance)
        {
            return (((Me.Totems[0].Unit != null) && (Me.Totems[0].Unit.Name != "Fire Totem")) && (GetDistance(Me.Totems[0].Unit, target) <= distance));
        }

        private static bool MyTotemWaterCheck(WoWUnit target, int distance)
        {
            return (((Me.Totems[2].Unit != null) && (Me.Totems[2].Unit.Name != "Water Totem")) && (GetDistance(Me.Totems[2].Unit, target) <= distance));
        }

        private static bool NeedFriendWindwalk()
        {
            return NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(unit => (((unit.Combat && unit.GotTarget) && IsEnemy(unit.CurrentTarget)) && DebuffRoot(unit)));
        }

        private static bool NeedGroudingTrap()
        {
            GroundingTrapPlayer = NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(player => player.Location.Distance(EnemyFreezingTrap.Location) < 8f);
            return BasicCheck(GroundingTrapPlayer);
        }

        private static bool NeedHealUnit(WoWUnit target)
        {
            return (NeedHealUnitHS.Contains(target.Entry) && target.IsFriendly);
        }

        private static bool NeedPurgeASAPEleEnh(WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => NeedPurgeASAPEleEnhHS.Contains(aura.Name));
        }

        private static bool NeedPurgeASAPResto(WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => NeedPurgeASAPRestoHS.Contains(aura.Name));
        }

        private static bool NeedSearingTotemResto(int dist)
        {
            return NearbyUnFriendlyUnits.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(unit => (((((Me.CurrentMap.Name == "Proving Grounds") || (Me.Combat && IsDummy(unit))) || ((unit.GotTarget && FarFriendlyPlayers.Contains(unit.CurrentTarget)) && (unit.MaxHealth > (MeMaxHealth * 0.5)))) && (GetDistance(unit) <= dist)) && InLineOfSpellSightCheck(unit)));
        }

        private static bool NeedTremor(WoWUnit target, int duration, bool writelog = true)
        {
            foreach (WoWAura aura in target.GetAllAuras())
            {
                if ((((aura.TimeLeft.TotalMilliseconds >= duration) && (aura.SpellId != 0x764b)) && (aura.SpellId != 0x20448)) && ((DebuffNeedTremor.Contains(aura.SpellId) || (aura.Spell.Mechanic == WoWSpellMechanic.Asleep)) || (((aura.Spell.Mechanic == WoWSpellMechanic.Charmed) || (aura.Spell.Mechanic == WoWSpellMechanic.Fleeing)) || (aura.Spell.Mechanic == WoWSpellMechanic.Horrified))))
                {
                    if (writelog)
                    {
                        Styx.Common.Logging.Write("NeedTremor {0} {1} ID: {2}", new object[] { target.SafeName, aura.Name, aura.SpellId });
                    }
                    return true;
                }
            }
            return false;
        }

        private static void OnBotStartedEvent(object o)
        {
            Styx.Common.Logging.Write("----------------------------------");
            Styx.Common.Logging.Write("Update Status on Bot Start");
            Styx.Common.Logging.Write("----------------------------------");
            THSettings.Instance.Pause = false;
            THSettings.Instance.UpdateStatus = true;
        }

        public override void OnButtonPress()
        {
            if (LoginCheckVal)
            {
                new THForm().ShowDialog();
            }
            else
            {
                new THLogin().ShowDialog();
            }
        }

        private static int OverrideToSpellId(string spellName)
        {
            switch (spellName)
            {
                case "Purify Spirit":
                    return 0x12d4a;

                case "Stormstrike":
                    return 0x43d4;
            }
            return 0;
        }

        private Composite PreBuffSelector()
        {
            if (this._preCombatBuffBehavior == null)
            {
                Styx.Common.Logging.Write("Initializing pre-combat buff behaviours.");
                this._preCombatBuffBehavior = new PrioritySelector(new Composite[] { MainRotation() });
            }
            return null;
        }

        public override void Pulse()
        {
            if (BasicCheck(Me) && StyxWoW.IsInWorld)
            {
                if (THSettings.Instance.UpdateStatus)
                {
                    this.UpdateStatus();
                }
                else
                {
                    GlobalCheck();
                    UseTrinketVoid();
                    ReturningFlag();
                    if (!Me.Mounted && (THSettings.Instance.AutoGhostWolfCancel || !MeHasAura("Ghost Wolf")))
                    {
                        WindShearInterruptVoid();
                        CapacitorProjection(THSettings.Instance.CapacitorProjectionMs);
                        GroundingCastInterruptVoid();
                        Tremor();
                        ShamanisticCC();
                        GhostWolfAvoidCC();
                        this.WarStompVoid();
                        this.StopCastingCheck();
                    }
                    if (((THSettings.Instance.PauseKeyUse && (THSettings.Instance.PauseKey != 0)) && ((GetAsyncKeyState(Keys.LControlKey) < 0) && (GetAsyncKeyState(IndexToKeys(THSettings.Instance.PauseKey)) < 0))) && (LastSwitch.AddSeconds(1.0) < DateTime.Now))
                    {
                        if (THSettings.Instance.Pause)
                        {
                            THSettings.Instance.Pause = false;
                            LastSwitch = DateTime.Now;
                            Styx.Common.Logging.Write("Pause Mode is OFF, Hold 1 second Ctrl + " + IndexToKeys(THSettings.Instance.PauseKey) + " to Override bot action.");
                        }
                        else
                        {
                            THSettings.Instance.Pause = true;
                            THSettings.Instance.UpdateStatus = true;
                            LastSwitch = DateTime.Now;
                            Styx.Common.Logging.Write("Pause Mode is ON, Hold 1 second Ctrl + " + IndexToKeys(THSettings.Instance.PauseKey) + " to resume bot action.");
                        }
                    }
                    if (THSettings.Instance.Burst && (BurstLast < DateTime.Now))
                    {
                        THSettings.Instance.Burst = false;
                        BurstLast = DateTime.Now;
                        Styx.Common.Logging.Write("Burst Mode is OFF");
                    }
                    if (((THSettings.Instance.BurstKey == 1) && !THSettings.Instance.Burst) && !DebuffCC(Me))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated On Cooldown");
                        THSettings.Instance.Burst = true;
                    }
                    if ((((THSettings.Instance.BurstKey == 2) && !THSettings.Instance.Burst) && (CurrentTargetAttackable(40.0, false, false) && Me.CurrentTarget.IsBoss)) && !DebuffCC(Me))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated On Cooldown (Boss Only)");
                        THSettings.Instance.Burst = true;
                    }
                    if ((((THSettings.Instance.BurstKey == 3) && !THSettings.Instance.Burst) && ((MeHasAura("Bloodlust") || MeHasAura("Heroism")) || (MeHasAura("Time Warp") || MeHasAura("Ancient Hysteria")))) && !DebuffCC(Me))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated On Bloodlust/Heroism/Time Warp/Ancient Hysteria");
                        THSettings.Instance.Burst = true;
                    }
                    if (((THSettings.Instance.BurstKey == 4) && !THSettings.Instance.Burst) && DebuffCCDuration(Me, 3000.0, false))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated on Lose Control");
                        THSettings.Instance.Burst = true;
                    }
                    if (((THSettings.Instance.BurstKey == 5) && !THSettings.Instance.Burst) && ((Me.HealthPercent < THSettings.Instance.BurstHP) && !DebuffCC(Me)))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated on My Health Low");
                        THSettings.Instance.Burst = true;
                    }
                    if ((((THSettings.Instance.BurstKey == 6) && !THSettings.Instance.Burst) && (BasicCheck(UnitHeal) && !UnitHeal.IsPet)) && ((HealWeightUnitHeal <= THSettings.Instance.BurstHP) && !DebuffCC(Me)))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated on Friend Health Low");
                        THSettings.Instance.Burst = true;
                    }
                    if ((((THSettings.Instance.BurstKey == 7) && !THSettings.Instance.Burst) && (CurrentTargetAttackable(40.0, false, false) && !Me.CurrentTarget.IsPet)) && (((Me.HealthPercent > THSettings.Instance.UrgentHeal) && (Me.CurrentTarget.HealthPercent <= THSettings.Instance.BurstHP)) && !DebuffCC(Me)))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated on Enemy Health Low");
                        THSettings.Instance.Burst = true;
                    }
                    if (((THSettings.Instance.BurstKey == 8) && !THSettings.Instance.Burst) && ((Me.ManaPercent < THSettings.Instance.BurstHP) && !DebuffCC(Me)))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated on My Mana Low");
                        THSettings.Instance.Burst = true;
                    }
                    if (((THSettings.Instance.BurstKey == 9) && !THSettings.Instance.Burst) && (BuffBurst(Me) && !DebuffCC(Me)))
                    {
                        BurstLast = DateTime.Now.AddSeconds(15.0);
                        Styx.Common.Logging.Write("Burst Mode Activated on Using Cooldown");
                        THSettings.Instance.Burst = true;
                    }
                    if (((THSettings.Instance.BurstKey > 9) && (GetAsyncKeyState(Keys.LControlKey) < 0)) && ((GetAsyncKeyState(IndexToKeys(THSettings.Instance.BurstKey - 9)) < 0) && (LastSwitch.AddSeconds(1.0) < DateTime.Now)))
                    {
                        if (THSettings.Instance.Burst)
                        {
                            THSettings.Instance.Burst = false;
                            LastSwitch = DateTime.Now;
                            Styx.Common.Logging.Write("Burst Mode is OFF, Hold 1 second Ctrl + " + IndexToKeys(THSettings.Instance.BurstKey - 8) + " to Turn Burst Mode ON.");
                        }
                        else if (!DebuffCC(Me))
                        {
                            THSettings.Instance.Burst = true;
                            LastSwitch = DateTime.Now;
                            BurstLast = DateTime.Now.AddSeconds(15.0);
                            Styx.Common.Logging.Write("Burst Mode is ON, Hold 1 second Ctrl + " + IndexToKeys(THSettings.Instance.BurstKey - 8) + " to Turn Burst Mode OFF.");
                        }
                    }
                }
            }
        }

        private static Composite PurgeASAPEleEnh()
        {
            return new Decorator(ret => ((((THSettings.Instance.PurgeASAP && (Me.ManaPercent >= THSettings.Instance.PurgeASAPMana)) && (BasicCheck(Me.CurrentTarget) && Me.CurrentTarget.IsPlayer)) && ((!CurrentTargetCheckInvulnerable && CurrentTargetCheckIsEnemy) && ((CurrentTargetCheckDist <= 30.0) && !CurrentTargetCheckInvulnerableMagic))) && NeedPurgeASAPEleEnh(Me.CurrentTarget)) && CanCastCheck("Purge", false), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Purge", Me.CurrentTarget, "PurgeASAPEleEnh");
            }));
        }

        private static Composite PurgeASAPResto()
        {
            return new Decorator(ret => ((THSettings.Instance.PurgeASAP && (HealWeightUnitHeal >= THSettings.Instance.PriorityHeal)) && ((Me.ManaPercent >= THSettings.Instance.PurgeASAPMana) && CanCastCheck("Purge", false))) && GetUnitUnitPurgeASAPResto(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Purge", UnitPurgeASAPResto, "PurgeASAP");
            }));
        }

        private static Composite PurgeNormal()
        {
            return new Decorator(ret => ((THSettings.Instance.PurgeNormal && (HealWeightUnitHeal >= THSettings.Instance.PriorityHeal)) && ((Me.ManaPercent >= THSettings.Instance.PurgeNormalMana) && CanCastCheck("Purge", false))) && GetUnitUnitPurgeNormalResto(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Purge", UnitPurgeNormalResto, "PurgeNormal");
            }));
        }

        private static Composite PurifySpiritFriendlyASAPComp()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => ((THSettings.Instance.PurifySpiritASAP && (((HealWeightUnitHeal >= THSettings.Instance.UrgentHeal) || Me.CurrentMap.IsDungeon) || (Me.CurrentMap.IsRaid || (Me.CurrentMap.Name == "Proving Grounds")))) && CanCastCheck("Purify Spirit", false)) && GetPlayerFriendlyPurifySpiritASAP(), new Styx.TreeSharp.Action(delegate (object param0) {
                SpellManager.StopCasting();
                CastSpell("Purify Spirit", PlayerFriendlyPurifySpiritASAP, "PurifySpiritFriendlyASAPComp");
            })) });
        }

        private static Composite PurifySpiritFriendlyComp()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.PurifySpiritDebuff && (GetPlayerFriendlyPurifySpiritLast < DateTime.Now)) && ((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent > 30.0))) && CanCastCheck("Purify Spirit", false)) && GetPlayerFriendlyPurifySpirit(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Purify Spirit", PlayerFriendlyPurifySpirit, "PurifySpiritFriendlyComp");
            })) });
        }

        private static Composite PurifySpiritFriendlyPvEComp()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.PurifySpiritDebuff && (UseSpecialization == 2)) && (Me.CurrentMap.IsRaid && (GetPlayerFriendlyPurifySpiritLast < DateTime.Now))) && (((HealWeightUnitHeal >= THSettings.Instance.PriorityHeal) && (Me.ManaPercent > 30.0)) && CanCastCheck("Purify Spirit", false))) && GetPlayerFriendlyPurifySpirit(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Purify Spirit", PlayerFriendlyPurifySpirit, "PurifySpiritFriendlyComp");
            })) });
        }

        private static Composite PurifySpiritMyRoot()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => ((THSettings.Instance.PurifySpiritASAP && (HealWeightUnitHeal >= THSettings.Instance.UrgentHeal)) && ((Me.ManaPercent > 30.0) && CanCastCheck("Purify Spirit", false))) && DebuffRootCanCleanse(Me), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Purify Spirit", Me, "PurifySpiritMyRoot");
            })) });
        }

        private static Composite RestorationRotation()
        {
            return new PrioritySelector(new Composite[] { 
                MovementMoveToLoS(ret => Me.CurrentTarget), MovementMoveStop(ret => Me.CurrentTarget, 10.0), TargetMyPetTarget(), new Styx.TreeSharp.Action(delegate (object param0) {
                    if (!Me.Mounted)
                    {
                        return RunStatus.Failure;
                    }
                    return RunStatus.Success;
                }), GhostWolfHoldComp(), AscendanceResto(), SpiritwalkersGrace(), ElementalMastery(), AncestralGuidance(), Stormlash(), Windwalk(), StoneBulwarkTotem(), AstralShift(), PurifySpiritFriendlyASAPComp(), PurifySpiritFriendlyPvEComp(), SpiritLink(), 
                GreaterHealingWaveAS(), GroundingLow(), Hex(), Capacitor(), PurgeASAPResto(), FlameShockRogueDruid(), TotemicRecall(), EarthElemental(), FireElemental(), HealingTideTotem(), HealingSurgeResIsSafetoCast(), GreaterHealingWaveIsSafetoCast(), PurifySpiritMyRoot(), HealingStreamTotem(), EarthShield(), Riptide(), 
                UnleashElementsRes(), FrostShockNearby(), HealingRain(), ChainHeal(), HealingSurgeRes(), WaterShieldAlways(), GreaterHealingWave(), BindElemental(), ManaTideTotem(), WaterShield(), Earthbind(), SearingTotemResto(), AttackResto(), HealingWave(), LightningBoltTelluricCurrents(), PurifySpiritFriendlyComp(), 
                PurgeNormal(), HealingWaveBaitInterrupt(), WaterWalking(), GhostWolfResto(), TemporaryEnchantment(), AutoRez()
             });
        }

        private static Composite RestRotation()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.AutoUseFood && (Me.ManaPercent <= THSettings.Instance.AutoUseFoodHP)) && ((UseSpecialization == 3) && !Me.Combat)) && ((!Me.IsSwimming && !IsMoving(Me)) && (!Me.IsCasting && !MeHasAura("Drink")))) && (Consumable.GetBestDrink(false) != null), new Styx.TreeSharp.Action(delegate (object param0) {
                StyxWoW.SleepForLagDuration();
                if (!MeHasAura("Drink"))
                {
                    Rest.DrinkImmediate();
                    StyxWoW.SleepForLagDuration();
                }
                if ((MeHasAura("Drink") && ((Me.ManaPercent < THSettings.Instance.DoNotHealAbove) || (UnitHealIsValid && (HealWeightUnitHeal <= THSettings.Instance.UrgentHeal)))) && !Me.Combat)
                {
                    return RunStatus.Running;
                }
                return RunStatus.Success;
            })), new Decorator(ret => (((THSettings.Instance.AutoUseFood && (Me.HealthPercent <= THSettings.Instance.AutoUseFoodHP)) && (!Me.Combat && !Me.IsSwimming)) && ((!IsMoving(Me) && !Me.IsCasting) && !MeHasAura("Food"))) && (Consumable.GetBestFood(false) != null), new Styx.TreeSharp.Action(delegate (object param0) {
                StyxWoW.SleepForLagDuration();
                if (!MeHasAura("Food"))
                {
                    Rest.FeedImmediate();
                    StyxWoW.SleepForLagDuration();
                }
                if ((MeHasAura("Food") && (Me.HealthPercent < THSettings.Instance.DoNotHealAbove)) && !Me.Combat)
                {
                    return RunStatus.Running;
                }
                return RunStatus.Success;
            })) });
        }

        private Composite RestSelector()
        {
            if (this._restBehavior == null)
            {
                Styx.Common.Logging.Write("Initializing rest behaviours.");
                this._restBehavior = new PrioritySelector(new Composite[] { RestRotation() });
            }
            return null;
        }

        private static void ReturningFlag()
        {
            if (SearchFlagTime >= DateTime.Now)
            {
                WoWGameObject obj2 = ObjectManager.GetObjectsOfType<WoWGameObject>().FirstOrDefault<WoWGameObject>(delegate (WoWGameObject obj) {
                    if (!(obj.Name == "Alliance Flag") && !(obj.Name == "Horde Flag"))
                    {
                        return false;
                    }
                    return obj.Distance <= 15.0;
                });
                if (obj2 != null)
                {
                    if (!IsOverrideModeOn)
                    {
                        Navigator.MoveTo(obj2.Location);
                    }
                    Me.SetFacing(obj2.Location);
                    obj2.Interact();
                    Styx.Common.Logging.Write("Trying to Return/Pick Up Dropped flag!");
                }
            }
        }

        private static Composite Riptide()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => ((THSettings.Instance.Riptide && (HealWeightUnitHeal <= THSettings.Instance.RiptideHP)) && CanCastCheck("Riptide", false)) && GetUnitUnitRiptide(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Riptide", UnitRiptide, "Riptide");
            })) });
        }

        private static void RiptideTidalWaves(WoWUnit target, string reason)
        {
            if ((THSettings.Instance.Riptide && !MeHasAura(0xd08e)) && CanCastCheck("Riptide", false))
            {
                CastSpell("Riptide", target, reason);
            }
        }

        private Composite RotationSelector()
        {
            if (this._combatBehavior == null)
            {
                Styx.Common.Logging.Write("Initializing combat behaviours.");
                this._combatBehavior = new PrioritySelector(new Composite[] { MainRotation() });
            }
            return null;
        }

        private static void SafelyFacingTarget(WoWUnit target)
        {
            if ((!IsUsingAFKBot || !IsMoving(Me)) && ((THSettings.Instance.AutoFace && !IsOverrideModeOn) && !Me.IsSafelyFacing(target)))
            {
                Me.SetFacing(target.Location);
                WoWMovement.ConstantFace(target.Guid);
            }
        }

        private static bool SafeUsingCooldown(WoWUnit target)
        {
            if (Me.CurrentMap.IsRaid)
            {
                return false;
            }
            return !target.GetAllAuras().Any<WoWAura>(aura => SafeUsingCooldownHS.Contains(aura.SpellId));
        }

        private static Composite SearingTotem()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.SearingTotem || !CurrentTargetAttackable((double) THSettings.Instance.SearingTotemDistance, false, false)) || (CurrentTargetCheckInvulnerableMagic || (Me.ManaPercent <= 20.0))) || (MyTotemFireCheck(Me, 40) || !CanCastCheck("Searing Totem", false)))
                {
                    return false;
                }
                return !MyTotemCheck("Searing Totem", Me.CurrentTarget, THSettings.Instance.SearingTotemDistance) || (((Me.CurrentTarget.IsPlayer && MyTotemCheck("Searing Totem", Me.CurrentTarget, THSettings.Instance.SearingTotemDistance)) && (GetDistance(Me.Totems[0].Unit, Me.CurrentTarget) > 10f)) && !GameWorld.TraceLine(Me.Totems[0].Unit.Location, Me.CurrentTarget.Location, GameWorld.CGWorldFrameHitFlags.HitTestBoundingModels | GameWorld.CGWorldFrameHitFlags.HitTestGround | GameWorld.CGWorldFrameHitFlags.HitTestMovableObjects | GameWorld.CGWorldFrameHitFlags.HitTestWMO));
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Searing Totem", Me.CurrentTarget, "SearingTotem");
            }));
        }

        private static Composite SearingTotemResto()
        {
            return new Decorator(ret => ((THSettings.Instance.SearingTotem && (HealWeightUnitHeal >= THSettings.Instance.PriorityHeal)) && (!MyTotemFireCheck(Me, 60) && CanCastCheck("Searing Totem", false))) && NeedSearingTotemResto(THSettings.Instance.SearingTotemDistance), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Searing Totem", Me, "SearingTotemResto");
            }));
        }

        private static void ShamanisticCC()
        {
            if (((THSettings.Instance.ShamanisticCC && HasGlyph.Contains("63280")) && ((LastBreakCC < DateTime.Now) && !SpellsCooldownCache.ContainsKey("Shamanistic Rage"))) && ((!Me.Mounted && Debuff63280Duration(Me, (double) THSettings.Instance.ShamanisticCCDuration, false)) && CanCastCheck("Shamanistic Rage", true)))
            {
                LastBreakCC = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
                CastSpell("Shamanistic Rage", Me, "ShamanisticCC");
            }
        }

        private static Composite ShamanisticRage()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => ((THSettings.Instance.ShamanisticRageHP && Me.Combat) && ((Me.HealthPercent <= THSettings.Instance.ShamanisticRageHPHP) && CanCastCheck("Shamanistic Rage", true))) && HasEnemyTargettingUnit(Me, 40f), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Shamanistic Rage", Me, "ShamanisticRageHP");
                return RunStatus.Failure;
            })), new Decorator(ret => ((THSettings.Instance.ShamanisticRageMN && Me.Combat) && ((Me.ManaPercent <= THSettings.Instance.ShamanisticRageMNMN) && CanCastCheck("Shamanistic Rage", true))) && HasEnemyTargettingUnit(Me, 40f), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Shamanistic Rage", Me, "ShamanisticRageHP");
                return RunStatus.Failure;
            })) });
        }

        private static bool ShouldFlameShockAoE()
        {
            return ((!Me.GotTarget || (MyAuraTimeLeft("Flame Shock", Me.CurrentTarget) >= 7000.0)) && (MyAuraStackCount("Lightning Shield", Me) <= 5.0));
        }

        private static bool ShouldSpiritwalkersGrace()
        {
            return BasicCheck(NearbyFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).FirstOrDefault<WoWUnit>(unit => ((TalentSort(unit) == 1) && (unit.Distance <= 10.0)) || ((((TalentSort(unit) > 1) && (TalentSort(unit) < 4)) && ((unit.Distance <= 40.0) && !DebuffCC(unit))) && InLineOfSpellSightCheck(unit))));
        }

        private static WoWSpell SpellFind(string spell)
        {
            SpellFindResults results;
            if (!SpellManager.FindSpell(spell, out results))
            {
                return null;
            }
            return (results.Override ?? results.Original);
        }

        private static bool SpellOnCooldown(int spell)
        {
            SpellFindResults results;
            if (!SpellManager.FindSpell(spell, out results))
            {
                return false;
            }
            if (results.Override == null)
            {
                return results.Original.Cooldown;
            }
            return results.Override.Cooldown;
        }

        private static bool SpellOnCooldown(string spell)
        {
            SpellFindResults results;
            if (!SpellManager.FindSpell(spell, out results))
            {
                return false;
            }
            if (results.Override == null)
            {
                return results.Original.Cooldown;
            }
            return results.Override.Cooldown;
        }

        private static void SpellsCooldownCacheAdd(string spellName, DateTime CooldownBack)
        {
            if ((UseSpecialization != 1) || (spellName != "Lava Burst"))
            {
                if (spellName.Contains("Shock") && !HasGlyph.Contains("55443"))
                {
                    SpellsCooldownCache.Add("Earth Shock", CooldownBack);
                    SpellsCooldownCache.Add("Flame Shock", CooldownBack);
                    SpellsCooldownCache.Add("Frost Shock", CooldownBack);
                }
                else if (((spellName == "Primal Strike") || (spellName == "Storm Strike")) || (spellName == "Stormblast"))
                {
                    SpellsCooldownCache.Add("Primal Strike", CooldownBack);
                    SpellsCooldownCache.Add("Storm Strike", CooldownBack);
                    SpellsCooldownCache.Add("Stormblast", CooldownBack);
                }
                else
                {
                    SpellsCooldownCache.Add(spellName, CooldownBack);
                }
            }
        }

        private static void SpellsCooldownCacheClear()
        {
            if (MeHasAura("Arena Preparation"))
            {
                SpellsCooldownCache.Clear();
            }
            else
            {
                foreach (string str in (from unit in SpellsCooldownCache
                    where unit.Value < DateTime.Now
                    select unit.Key).ToList<string>())
                {
                    try
                    {
                        SpellsCooldownCache.Remove(str);
                    }
                    catch (Exception)
                    {
                        Styx.Common.Logging.Write("Fail to SpellsCooldownCache.Remove({0})", new object[] { str });
                        throw;
                    }
                }
            }
        }

        private static Composite SpiritLink()
        {
            return new Decorator(ret => (((((THSettings.Instance.SpiritLink && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.SpiritLinkHP) && !MyTotemCheck("Capacitor Totem", Me, 40))) && ((UnitHeal.Combat && !UnitHeal.IsPet) && !Invulnerable(UnitHeal))) && ((UnitHeal.Distance <= 10.0) || CanCastCheck("Totemic Projection", false))) && (HaveDPSTarget(UnitHeal) && CanCastCheck("Spirit Link Totem", false))) && (CountUnitSpiritLink(UnitHeal) >= THSettings.Instance.SpiritLinkUnit), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Spirit Link Totem", Me, "Spirit Link Totem");
                StyxWoW.SleepForLagDuration();
                if ((UnitHeal.Distance > 10.0) && CanCastCheck("Totemic Projection", false))
                {
                    CastSpell("Totemic Projection", Me, "Totemic Projection Spirit Link Totem");
                    ObjectManager.Update();
                    SpellManager.ClickRemoteLocation(UnitHeal.Location);
                }
            }));
        }

        private static Composite SpiritwalkersGrace()
        {
            return new Decorator(ret => (((THSettings.Instance.SpiritwalkersGrace && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.SpiritwalkersGraceHP) && UnitHeal.Combat)) && ((!UnitHeal.IsPet && !Invulnerable(UnitHeal)) && CanCastCheck("Spiritwalker's Grace", true))) && ShouldSpiritwalkersGrace(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Spiritwalker's Grace", Me, "SpiritwalkersGrace");
                return RunStatus.Failure;
            }));
        }

        private static Composite StoneBulwarkTotem()
        {
            return new Decorator(ret => (((THSettings.Instance.StoneBulwarkTotem && Me.Combat) && ((Me.HealthPercent <= THSettings.Instance.StoneBulwarkTotemHP) && !MyTotemCheck("Earthgrab Totem", Me, 40))) && (!MyTotemCheck("Earth Elemental Totem", Me, 40) && CanCastCheck("Stone Bulwark Totem", false))) && HasEnemyNear(Me, 35f), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Stone Bulwark Totem", Me, "StoneBulwarkTotemHP");
            }));
        }

        private void StopCastingCheck()
        {
            if (((StopCastingCheckLast <= DateTime.Now) || Me.CurrentMap.IsArena) && ((LastCastTime + TimeSpan.FromMilliseconds(2000.0)) >= DateTime.Now))
            {
                StopCastingCheckLast = DateTime.Now + TimeSpan.FromMilliseconds(50.0);
                if (Me.IsCasting)
                {
                    try
                    {
                        if (Me.CastingSpell.Id == 0xc93a)
                        {
                            if (!BasicCheck(LastCastUnit))
                            {
                                SpellManager.StopCasting();
                            }
                            if ((InvulnerableSpell(LastCastUnit) || DebuffCCDuration(LastCastUnit, 3000.0, false)) || !CanHex(LastCastUnit))
                            {
                                SpellManager.StopCasting();
                                Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Hex: Unit is CC/Sharpshifted");
                                return;
                            }
                        }
                        if ((((UseSpecialization == 3) && (Me.CastingSpell.Id == 0x193)) && (UnitHealIsValid && HasGlyph.Contains("55453"))) && ((Me.ManaPercent > THSettings.Instance.UrgentHeal) && (UnitHeal.HealthPercent < THSettings.Instance.UrgentHeal)))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Telluric Currents. Someone Need Urgent Heal!");
                        }
                        else if (((UseSpecialization == 2) && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && ((Me.CastingSpell.Id == 0x193) && CurrentTargetAttackable(5.0, false, false)))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Lightning Bolt: Enemy in Melee Range");
                        }
                        else if (((UseSpecialization == 1) && ((Me.CastingSpell.Id == 0x193) || (Me.CastingSpell.Id == 0x1a5))) && (MeHasAura(0x12fc2) && (Me.CurrentCastTimeLeft.TotalMilliseconds > MyLatency)))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Lightning Bolt/Chain Lightning: Lava Burst Proc");
                        }
                        else if (((UseSpecialization == 1) && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && (((Me.CastingSpell.Id == 0x1c916) && (Me.CurrentCastTimeLeft.TotalMilliseconds > MyLatency)) && (MeHasAura(0x12fc2) && HaveInterrupterRound(Me))))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Elemental Blash: Lava Burst Proc and Interrupter Nearby");
                        }
                        else if ((((UseSpecialization == 3) && (LastCastSpell == "Greater Healing Wave")) && (Me.CastingSpell.Id == 0x12ea0)) && ((LastCastUnit.HealthPercent > THSettings.Instance.DoNotHealAbove) || (LastCastUnit.HealthPercent > ((THSettings.Instance.GreaterHealingWaveHP + 20) + THSettings.Instance.HealBalancing))))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Save Mana Greater Healing Wave");
                        }
                        else if ((((UseSpecialization == 3) && (LastCastSpell == "Chain Heal")) && (Me.CastingSpell.Id == 0x428)) && ((LastCastUnit.HealthPercent > THSettings.Instance.DoNotHealAbove) || (LastCastUnit.HealthPercent > ((THSettings.Instance.ChainHealHP + 20) + THSettings.Instance.HealBalancing))))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Save Mana Chain Heal");
                        }
                        else if ((((UseSpecialization == 3) && (LastCastSpell == "Healing Surge")) && (Me.CastingSpell.Id == 0x1f44)) && ((LastCastUnit.HealthPercent > THSettings.Instance.DoNotHealAbove) || (LastCastUnit.HealthPercent > ((THSettings.Instance.HealingSurgeResHP + 20) + THSettings.Instance.HealBalancing))))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Save Mana Healing Surge");
                        }
                        else if (((((UseSpecialization == 3) && !Me.CurrentMap.IsDungeon) && (!Me.CurrentMap.IsRaid && (Me.CurrentMap.Name != "Proving Grounds"))) && (((LastCastSpell == "Healing Wave") && (Me.CastingSpell.Id == 0x14b)) && ((Me.ManaPercent > 30.0) && (Me.CurrentCastTimeLeft.TotalMilliseconds > 1300.0)))) && (((LastCastUnit.HealthPercent < (THSettings.Instance.GreaterHealingWaveHP + THSettings.Instance.HealBalancing)) && MyAura("Tidal Waves", Me)) && (LastCastUnit.Combat || Me.Combat)))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Healing Wave. Need Faster Heal!");
                        }
                        else if ((((UseSpecialization == 3) && Me.CurrentMap.IsRaid) && ((LastCastSpell == "Healing Wave") && (Me.CastingSpell.Id == 0x14b))) && (LastCastUnit.HealthPercent >= (THSettings.Instance.DoNotHealAbove + THSettings.Instance.HealBalancing)))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Save Mana Healing Wave");
                        }
                        else if (((UseSpecialization == 3) && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && (((LastCastSpell == "Healing Wave") && (Me.CastingSpell.Id == 0x14b)) && ((LastCastUnit.HealthPercent >= (THSettings.Instance.DoNotHealAbove + THSettings.Instance.HealBalancing)) && (Me.CurrentCastTimeLeft.TotalMilliseconds > rnd.Next(600, 0x3e8)))))
                        {
                            SpellManager.StopCasting();
                            Styx.Common.Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: HealingWaveBaitInterrupt");
                        }
                    }
                    catch (Exception)
                    {
                        Styx.Common.Logging.Write("StopCastingCheck Fail");
                        throw;
                    }
                }
            }
        }

        private static Composite Stormblast()
        {
            return new Decorator(ret => (((THSettings.Instance.Stormstrike && CurrentTargetAttackable(30.0, false, false)) && (!CurrentTargetCheckInvulnerablePhysic && SpellManager.HasSpell("Stormblast"))) && FacingOverride(Me.CurrentTarget)) && CanCastCheck("Primal Strike", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Primal Strike", Me.CurrentTarget, "Stormblast");
            }));
        }

        private static Composite Stormlash()
        {
            return new Decorator(ret => (((THSettings.Instance.StormlashCooldown || (THSettings.Instance.StormlashBurst && THSettings.Instance.Burst)) || (THSettings.Instance.StormlashEnemy && StormlashEnemy())) && ((Me.Combat && !MyTotemAirCheck(Me, 40)) && CanCastCheck("Stormlash Totem", false))) && HasEnemyNear(Me, 30f), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Stormlash Totem", Me, "Stormlash");
            }));
        }

        private static bool StormlashEnemy()
        {
            return NearbyUnFriendlyPlayers.Where<WoWUnit>(new Func<WoWUnit, bool>(Classname.BasicCheck)).Any<WoWUnit>(unit => ((unit.HealthPercent <= THSettings.Instance.StormlashEnemyHP) && HasFriendDPSTarget(unit)));
        }

        private static Composite Stormstrike()
        {
            return new Decorator(ret => ((THSettings.Instance.Stormstrike && CurrentTargetAttackable(5.0, false, false)) && (!CurrentTargetCheckInvulnerablePhysic && FacingOverride(Me.CurrentTarget))) && CanCastCheck("Stormstrike", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Stormstrike", Me.CurrentTarget, "Stormstrike");
            }));
        }

        private static void SVNCheck()
        {
            try
            {
                Styx.Common.Logging.Write("Newest SVN Revision: " + GetSVNRevision());
            }
            catch (Exception)
            {
                Styx.Common.Logging.Write("Can not get GetSVNRevision");
                return;
            }
            try
            {
                Styx.Common.Logging.Write("You are using Revision: " + GetLocalRevision());
            }
            catch (Exception)
            {
                Styx.Common.Logging.Write("Can not get GetLocalRevision");
                return;
            }
            if (((GetLocalRevision() != 0) && (GetSVNRevision() != 0)) && (GetSVNRevision() != GetLocalRevision()))
            {
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("A newer version with Improved Logic");
                Styx.Common.Logging.Write("And Bug Fix just uploaded to SVN server!");
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("Please update to the lastest Revision " + GetSVNRevision());
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("To Update please Close Honorbuddy");
                Styx.Common.Logging.Write("Then open folder");
                Styx.Common.Logging.Write(Path.Combine(Utilities.AssemblyDirectory, "Routines"));
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("Right Click Folder " + CombatRoutineFolder);
                Styx.Common.Logging.Write(" > SVN Update working copy. (If you see that option)");
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("Right Click Folder " + CombatRoutineFolder);
                Styx.Common.Logging.Write(" > SVN Update");
                Styx.Common.Logging.Write("----------------------------------");
            }
        }

        private static Composite SWStart()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (WriteSW)
                {
                    sw.Reset();
                    sw.Start();
                }
                return RunStatus.Failure;
            });
        }

        private static Composite SWStop(string FunctionName)
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (WriteSW)
                {
                    sw.Stop();
                    Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "{0} ms - {1} ", new object[] { sw.Elapsed.TotalMilliseconds, FunctionName });
                    sw.Reset();
                    sw.Start();
                }
                return RunStatus.Failure;
            });
        }

        private static void SWStopVoid(string FunctionName)
        {
            if (WriteSW)
            {
                sw.Stop();
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "{0} ms - {1} ", new object[] { sw.Elapsed.TotalMilliseconds, FunctionName });
                sw.Reset();
                sw.Start();
            }
        }

        private static Composite swtotalReset()
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (WriteSW)
                {
                    WriteSW = false;
                }
                if (!WriteSW && (swtotal.Elapsed.TotalSeconds > 10.0))
                {
                    WriteSW = true;
                }
                if (!swtotal.IsRunning || (swtotal.Elapsed.TotalSeconds > 10.0))
                {
                    swtotal.Reset();
                    swtotal.Start();
                }
                return RunStatus.Failure;
            });
        }

        private static byte TalentSort(WoWUnit target)
        {
            if ((target != null) && target.IsValid)
            {
                switch (target.Class)
                {
                    case WoWClass.Warrior:
                        return 1;

                    case WoWClass.Paladin:
                        if (target.MaxMana <= (target.MaxHealth / 2))
                        {
                            return 1;
                        }
                        return 4;

                    case WoWClass.Hunter:
                        return 2;

                    case WoWClass.Rogue:
                        return 1;

                    case WoWClass.Priest:
                        if (!UnitHasAura(0x1c0c4, target))
                        {
                            return 4;
                        }
                        return 3;

                    case WoWClass.DeathKnight:
                        return 1;

                    case WoWClass.Shaman:
                        if (target.MaxMana >= (target.MaxHealth / 2))
                        {
                            if (UnitHasAura(0x3f55, target))
                            {
                                return 4;
                            }
                            return 3;
                        }
                        return 1;

                    case WoWClass.Mage:
                        return 3;

                    case WoWClass.Warlock:
                        return 3;

                    case WoWClass.Monk:
                        if (!UnitHasAura(0x1c17e, target))
                        {
                            return 1;
                        }
                        return 4;

                    case WoWClass.Druid:
                        if (target.MaxMana >= (target.MaxHealth / 2))
                        {
                            if (UnitHasAura(0x1a0ef, target))
                            {
                                return 4;
                            }
                            return 3;
                        }
                        return 1;
                }
            }
            return 0;
        }

        private static string TalentSortRole(WoWUnit target)
        {
            switch (TalentSort(target))
            {
                case 1:
                    return "Melee";

                case 2:
                    return "Range DPS";

                case 3:
                    return "Range DPS";

                case 4:
                    return "Healer";
            }
            return "Unknow";
        }

        private static byte TalentSortSimple(WoWUnit target)
        {
            byte num = TalentSort(target);
            if (num == 4)
            {
                return 4;
            }
            if ((num < 4) && (num > 0))
            {
                return 1;
            }
            return 0;
        }

        private static Composite TargetMyPetTarget()
        {
            return new Decorator(ret => (((!CurrentTargetAttackable(40.0, false, false) && Me.Combat) && (IsUsingAFKBot && !Me.CurrentMap.IsArena)) && !Me.CurrentMap.IsBattleground) && GetUnitAttackingMyPet(), new Styx.TreeSharp.Action(delegate (object param0) {
                Styx.Common.Logging.Write(Styx.Common.LogLevel.Diagnostic, "TargetMyPetTarget");
                UnitAttackingMyPet.Target();
                return RunStatus.Failure;
            }));
        }

        private static Composite TemporaryEnchantment()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.WeaponMainHand > 0) && (Me.Inventory.Equipped.MainHand != null)) && (Me.Inventory.Equipped.MainHand.TemporaryEnchantment.Id != ImbuesIdToTemporaryEnchantmentId(THSettings.Instance.WeaponMainHand))) && CanCastCheck(ImbuesIdToName(THSettings.Instance.WeaponMainHand), false), new Styx.TreeSharp.Action(delegate (object ret) {
                Lua.DoString("RunMacroText(\"/click TempEnchant1\")", "WoW.lua");
                Lua.DoString("RunMacroText(\"/click TempEnchant2\")", "WoW.lua");
                StyxWoW.SleepForLagDuration();
                CastSpell(ImbuesIdToName(THSettings.Instance.WeaponMainHand), Me, "MainHand: " + ImbuesIdToName(THSettings.Instance.WeaponMainHand));
            })), new Decorator(ret => (((THSettings.Instance.AutoWeaponImbues && (UseSpecialization != 1)) && ((UseSpecialization != 3) && (Me.Inventory.Equipped.OffHand != null))) && (Me.Inventory.Equipped.OffHand.TemporaryEnchantment.Id != ImbuesIdToTemporaryEnchantmentId(THSettings.Instance.WeaponOffHand))) && CanCastCheck(ImbuesIdToName(THSettings.Instance.WeaponOffHand), false), new Styx.TreeSharp.Action(delegate (object ret) {
                if (Me.Inventory.Equipped.OffHand.TemporaryEnchantment.Id == 0)
                {
                    StyxWoW.SleepForLagDuration();
                    CastSpell(ImbuesIdToName(THSettings.Instance.WeaponOffHand), Me, "OffHand: " + ImbuesIdToName(THSettings.Instance.WeaponOffHand));
                    StyxWoW.SleepForLagDuration();
                }
                else
                {
                    StyxWoW.SleepForLagDuration();
                    Lua.DoString("RunMacroText(\"/click TempEnchant1\")", "WoW.lua");
                    StyxWoW.SleepForLagDuration();
                    Lua.DoString("RunMacroText(\"/click TempEnchant2\")", "WoW.lua");
                    StyxWoW.SleepForLagDuration();
                }
            })) });
        }

        private static Composite Thunderstorm()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (THSettings.Instance.Thunderstorm && CanCastCheck("Thunderstorm", false)) && (CountUnitThunderstorm() >= THSettings.Instance.ThunderstormUnit), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Thunderstorm", Me, "Thunderstorm");
            })) });
        }

        private static Composite ThunderstormCast()
        {
            return new Decorator(ret => ((THSettings.Instance.ThunderstormCast && (LastInterrupt < DateTime.Now)) && (Me.Combat && CanCastCheck("Thunderstorm", true))) && GetUnitThuderstormInterrupt(), new Styx.TreeSharp.Action(delegate (object param0) {
                LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
                CastSpell("Thunderstorm", Me, "ThunderstormCast");
            }));
        }

        private static Composite ThunderstormMana()
        {
            return new Decorator(ret => ((THSettings.Instance.ThunderstormMana && Me.Combat) && (Me.ManaPercent <= THSettings.Instance.ThunderstormManaMN)) && CanCastCheck("Thunderstorm", false), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Thunderstorm", Me, "ThunderstormMana");
            }));
        }

        private static Composite ThunderstormMelee()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (THSettings.Instance.ThunderstormMelee && CanCastCheck("Thunderstorm", false)) && (CountUnitThunderstormMelee() >= THSettings.Instance.ThunderstormMeleeUnit), new Styx.TreeSharp.Action(delegate (object ret) {
                CastSpell("Thunderstorm", Me, "ThunderstormMelee");
            })) });
        }

        private static Composite TotemicRecall()
        {
            return new Decorator(ret => ((((UseSpecialization == 3) && (Me.ManaPercent < 90.0)) && ((Me.CurrentMap.IsDungeon || Me.CurrentMap.IsRaid) || (Me.CurrentMap.Name == "Proving Grounds"))) && ((MyTotemCheck("Healing Stream Totem", Me, 100) && MyTotemCheckExpires("Healing Stream Totem", 0xfa0)) && !HasImportantTotem())) && CanCastCheck("Totemic Recall", true), new Styx.TreeSharp.Action(delegate (object param0) {
                if (Me.IsCasting)
                {
                    SpellManager.StopCasting();
                }
                CastSpell("Totemic Recall", Me, "TotemicRecall");
            }));
        }

        private static int TotemNametoEntry(string totemName)
        {
            switch (totemName)
            {
                case "Capacitor Totem":
                    return 0xef3d;

                case "Grounding Totem":
                    return 0x1725;

                case "Stormlash Totem":
                    return 0x7d02;

                case "Windwalk Totem":
                    return 0xe945;

                case "Earthbind Totem":
                    return 0xa46;

                case "Earthgrab Totem":
                    return 0xec91;

                case "Earth Elemental Totem":
                    return 0x3c46;

                case "Tremor Totem Totem":
                    return 0x1719;

                case "Stone Bulwark Totem":
                    return 0xe943;

                case "Fire Elemental Totem":
                    return 0x3c4f;

                case "Searing Totem":
                    return 0x9db;

                case "Magma Totem":
                    return 0x1729;

                case "Spirit Link Totem":
                    return 0xcf0e;

                case "Mana Tide Totem":
                    return 0x28e3;

                case "Healing Tide Totem":
                    return 0xe974;

                case "Healing Stream Totem":
                    return 0xdc7;
            }
            return 0;
        }

        private static void Tremor()
        {
            if ((THSettings.Instance.Tremor && (LastBreakCC <= DateTime.Now)) && ((!Me.Mounted && CanCastCheck("Tremor Totem", false)) && GetUnitNeedTremor()))
            {
                LastBreakCC = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
                CastSpell("Tremor Totem", Me, "Tremor");
            }
        }

        private static bool UnitHasAura(int auraID, WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => (aura.SpellId == auraID));
        }

        private static bool UnitHasAura(string auraName, WoWUnit target)
        {
            return target.GetAllAuras().Any<WoWAura>(aura => (aura.Name == auraName));
        }

        private static void UnleaseElementEarthLiving(bool Enabled, WoWUnit UnitToUnleaseElementEarthLiving)
        {
            if (((Enabled && (Me.Inventory.Equipped.MainHand != null)) && ((Me.Inventory.Equipped.MainHand.TemporaryEnchantment.Id == 0xd11) && BasicCheck(UnitToUnleaseElementEarthLiving))) && (!MeHasAura(0x11fd5) && CanCastCheck("Unleash Elements", false)))
            {
                CastSpell("Unleash Elements", UnitToUnleaseElementEarthLiving, "Unleash Elements before CH/GHW/HR/HS");
            }
        }

        private static Composite UnleashElementsEle()
        {
            return new Decorator(ret => ((THSettings.Instance.UnleashElementsEle && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground)) && ((IsMoving(Me) && CurrentTargetAttackable(40.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget)))) && CanCastCheck("Unleash Elements", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Unleash Elements", Me.CurrentTarget, "UnleashElementsEle");
            }));
        }

        private static Composite UnleashElementsEnh()
        {
            return new Decorator(ret => ((THSettings.Instance.UnleashElementsEnh && CurrentTargetAttackable(40.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget))) && CanCastCheck("Unleash Elements", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Unleash Elements", Me.CurrentTarget, "UnleashElementsEnh");
            }));
        }

        private static Composite UnleashElementsEnhSnare()
        {
            return new Decorator(ret => (((THSettings.Instance.UnleashElementsEnh && CurrentTargetAttackable(40.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget))) && (((Me.Inventory.Equipped.OffHand != null) && (Me.Inventory.Equipped.OffHand.TemporaryEnchantment.Id == 2)) && !InvulnerableRootandSnare(Me.CurrentTarget))) && CanCastCheck("Unleash Elements", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Unleash Elements", Me.CurrentTarget, "UnleashElementsEnhSnare");
            }));
        }

        private static Composite UnleashElementsEnhUnleashedFury()
        {
            return new Decorator(ret => ((THSettings.Instance.UnleashElementsEnh && CurrentTargetAttackable(40.0, false, false)) && (!CurrentTargetCheckInvulnerableMagic && FacingOverride(Me.CurrentTarget))) && CanCastCheck("Unleash Elements", false), new Styx.TreeSharp.Action(delegate (object param0) {
                SafelyFacingTarget(Me.CurrentTarget);
                CastSpell("Unleash Elements", Me.CurrentTarget, "UnleashElementsEnhUnleashedFury");
            }));
        }

        private static Composite UnleashElementsRes()
        {
            return new Decorator(ret => ((THSettings.Instance.UnleashElementsRes && UnitHealIsValid) && (HealWeightUnitHeal <= THSettings.Instance.UnleashElementsResHP)) && CanCastCheck("Unleash Elements", false), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Unleash Elements", UnitHeal, "UnleashElementsRes");
            }));
        }

        private static void UpdateEventHandler()
        {
            if (!CombatLogAttachedPvP && (Me.CurrentMap.IsArena || Me.CurrentMap.IsBattleground))
            {
                AttachCombatLogEventPvP();
            }
            if ((CombatLogAttachedPvP && !Me.CurrentMap.IsArena) && !Me.CurrentMap.IsBattleground)
            {
                DetachCombatLogEventPvP();
            }
            if (((IsUsingAFKBot && !EventHandlers.CombatLogAttached) && (!Me.CurrentMap.IsArena && !Me.CurrentMap.IsBattleground)) && (!Me.CurrentMap.IsDungeon && !Me.CurrentMap.IsRaid))
            {
                EventHandlers.AttachCombatLogEvent();
            }
            if (EventHandlers.CombatLogAttached && ((!IsUsingAFKBot || Me.CurrentMap.IsArena) || ((Me.CurrentMap.IsBattleground || Me.CurrentMap.IsDungeon) || Me.CurrentMap.IsRaid)))
            {
                EventHandlers.DetachCombatLogEvent();
            }
        }

        private static void UpdateGroupChangeEvent(object sender, LuaEventArgs args)
        {
            if (IGroupHealingOn())
            {
                Styx.Common.Logging.Write("Update Selective Group Healing on Group Member Change");
                UpdateGroupHealingMembers();
            }
        }

        private static void UpdateGroupHealingMembers()
        {
            GroupHealingMembers.Clear();
            if (IGroupHealingOn())
            {
                foreach (WoWPartyMember member in GroupMembers)
                {
                    if ((member.ToPlayer() != null) && ((((THSettings.Instance.Group1 && (member.GroupNumber == 0)) || (THSettings.Instance.Group2 && (member.GroupNumber == 1))) || ((THSettings.Instance.Group3 && (member.GroupNumber == 2)) || (THSettings.Instance.Group4 && (member.GroupNumber == 3)))) || (((THSettings.Instance.Group5 && (member.GroupNumber == 4)) || (THSettings.Instance.Group6 && (member.GroupNumber == 5))) || ((THSettings.Instance.Group7 && (member.GroupNumber == 6)) || (THSettings.Instance.Group8 && (member.GroupNumber == 7))))))
                    {
                        Styx.Common.Logging.Write(string.Concat(new object[] { "Add ", member.ToPlayer().Class, " in Group: ", Convert.ToByte(member.GroupNumber) + 1, " to Selective Group Healing" }));
                        GroupHealingMembers.Add(member.ToPlayer());
                    }
                }
                if (GroupHealingMembers.Any<WoWPlayer>())
                {
                    Styx.Common.Logging.Write("----------------------------------");
                    Styx.Common.Logging.Write("You are assigned to Heal " + GroupHealingMembers.Count<WoWPlayer>() + " Members");
                    Styx.Common.Logging.Write("You will also heal your Target, your Focus and Yourself!");
                    Styx.Common.Logging.Write("----------------------------------");
                }
            }
        }

        private static void UpdateMyGlyph()
        {
            HasGlyph = "";
            HasGlyphName = "";
            int returnVal = Lua.GetReturnVal<int>("return GetNumGlyphSockets()", 0);
            if (returnVal != 0)
            {
                for (int i = 1; i <= returnVal; i++)
                {
                    int id = Lua.GetReturnVal<int>(string.Format("local enabled, glyphType, glyphTooltipIndex, glyphSpellID, icon = GetGlyphSocketInfo({0});if (enabled) then return glyphSpellID else return 0 end", i), 0);
                    try
                    {
                        if (id > 0)
                        {
                            HasGlyphName = string.Concat(new object[] { HasGlyphName, "[", WoWSpell.FromId(id), " - ", id, "] " });
                            HasGlyph = string.Concat(new object[] { HasGlyph, "[", id, "] " });
                        }
                        else
                        {
                            Styx.Common.Logging.Write("Glyphdetection - No Glyph in slot " + i);
                        }
                    }
                    catch (Exception exception)
                    {
                        Styx.Common.Logging.Write("We couldn't detect your Glyphs");
                        Styx.Common.Logging.Write("Report this message to us: " + exception);
                    }
                }
            }
            Styx.Common.Logging.Write("----------------------------------");
            Styx.Common.Logging.Write("Glyph:");
            Styx.Common.Logging.Write(HasGlyphName);
            Styx.Common.Logging.Write("----------------------------------");
        }

        private static void UpdateMyGlyphEvent(object sender, LuaEventArgs args)
        {
            UpdateMyGlyph();
        }

        private static void UpdateMyLatency()
        {
            MyLatency = StyxWoW.WoWClient.Latency;
            if (MyLatency > 400.0)
            {
                MyLatency = 400.0;
            }
        }

        private void UpdateStatus()
        {
            if (THSettings.Instance.UpdateStatus)
            {
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("Building Rotation base on current Talents and Glyphs......");
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("");
                UpdateMyGlyph();
                UpdateMyLatency();
                UpdateGroupHealingMembers();
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("Hold 1 second Control + " + IndexToKeys(THSettings.Instance.PauseKey) + " To Toggle Pause Mode.");
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("");
                if (THSettings.Instance.BurstKey > 9)
                {
                    Styx.Common.Logging.Write("----------------------------------");
                    Styx.Common.Logging.Write("Hold 1 second Control + " + IndexToKeys(THSettings.Instance.BurstKey - 9) + " To Toggle Burst Mode");
                    Styx.Common.Logging.Write("----------------------------------");
                    Styx.Common.Logging.Write("");
                }
                if ((((TreeRoot.Current.Name == "Questing") || (TreeRoot.Current.Name == "[BETA] Grindbuddy")) || ((TreeRoot.Current.Name == "ArcheologyBuddy") || (TreeRoot.Current.Name == "Auto Angler"))) || (((TreeRoot.Current.Name == "Gatherbuddy2") || (TreeRoot.Current.Name == "Grind Bot")) || (((TreeRoot.Current.Name == "BGBuddy") || (TreeRoot.Current.Name == "DungeonBuddy")) || (TreeRoot.Current.Name == "Mixed Mode"))))
                {
                    IsUsingAFKBot = true;
                }
                else
                {
                    IsUsingAFKBot = false;
                }
                if (Me.Specialization == WoWSpec.ShamanElemental)
                {
                    UseSpecialization = 1;
                }
                else if (Me.Specialization == WoWSpec.ShamanRestoration)
                {
                    UseSpecialization = 3;
                }
                else
                {
                    UseSpecialization = 2;
                }
                MeGuid = Me.Guid;
                MeMaxHealth = Me.MaxHealth;
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("Building Rotation Completed");
                Styx.Common.Logging.Write("----------------------------------");
                Styx.Common.Logging.Write("");
                THSettings.Instance.UpdateStatus = false;
                SVNCheck();
            }
        }

        private static void UpdateStatusEvent(object sender, LuaEventArgs args)
        {
            THSettings.Instance.UpdateStatus = true;
        }

        private static Composite UseBattleStandard()
        {
            return new Decorator(ret => (((THSettings.Instance.BattleStandard && Me.Combat) && ((Me.HealthPercent <= THSettings.Instance.BattleStandardHP) && (Me.CurrentTarget != null))) && (Me.CurrentTarget.HealthPercent > Me.HealthPercent)) && Me.CurrentMap.IsBattleground, new Styx.TreeSharp.Action(delegate (object param0) {
                if (Me.IsAlliance)
                {
                    WoWItem item = Me.BagItems.FirstOrDefault<WoWItem>(o => o.Entry == 0x48ae);
                    if ((!MeHasAura("Alliance Battle Standard") && (item != null)) && (item.CooldownTimeLeft.TotalMilliseconds <= MyLatency))
                    {
                        item.Use();
                        Styx.Common.Logging.Write("Use Battle Standard at " + Me.HealthPercent + "%");
                    }
                }
                if (Me.IsHorde)
                {
                    WoWItem item2 = Me.BagItems.FirstOrDefault<WoWItem>(o => o.Entry == 0x48af);
                    if ((!MeHasAura("Horde Battle Standard") && (item2 != null)) && (item2.CooldownTimeLeft.TotalMilliseconds <= MyLatency))
                    {
                        item2.Use();
                        Styx.Common.Logging.Write("Use Battle Standard at " + Me.HealthPercent + "%");
                    }
                }
                return RunStatus.Failure;
            }));
        }

        private static Composite UseHealthStoneHP()
        {
            return new Decorator(ret => ((THSettings.Instance.HealthStone && Me.Combat) && ((Me.HealthPercent < THSettings.Instance.HealthStoneHP) && (Me.CurrentTarget != null))) && (Me.CurrentTarget.HealthPercent > Me.HealthPercent), new Styx.TreeSharp.Action(delegate (object param0) {
                WoWItem item = Me.BagItems.FirstOrDefault<WoWItem>(o => o.Entry == 0x1588);
                if ((item != null) && (item.CooldownTimeLeft.TotalMilliseconds <= MyLatency))
                {
                    item.Use();
                    Styx.Common.Logging.Write("Use HealthStoneHP at " + Me.HealthPercent + "%");
                }
                return RunStatus.Failure;
            }));
        }

        private static Composite UseProfession()
        {
            Composite[] children = new Composite[] { 
                new Decorator(ret => ((THSettings.Instance.ProfBuff == 1) && (Me.Inventory.Equipped.Hands != null)) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Gloves Buff Activated on Cooldown");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 2) && (Me.Inventory.Equipped.Hands != null)) && (CurrentTargetAttackable(30.0, false, false) && Me.CurrentTarget.IsBoss)) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Gloves Buff Activated on Cooldown (Boss Only");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 3) && THSettings.Instance.Burst) && (Me.Inventory.Equipped.Hands != null)) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Gloves Buff Activated on Burst Mode");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 4) && (Me.Inventory.Equipped.Hands != null)) && (CurrentTargetAttackable(30.0, false, false) && DebuffCCDuration(Me, 3000.0, false))) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Gloves Buff Activated on Lose Control");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 5) && (Me.Inventory.Equipped.Hands != null)) && (Me.HealthPercent < THSettings.Instance.ProfBuffHP)) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: GLoves Buff Activated on Low HP");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 6) && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.ProfBuffHP) && (Me.Inventory.Equipped.Hands != null))) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Gloves Buff Activated on Friendly Unit Low HP");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.ProfBuff == 7) && (Me.Inventory.Equipped.Hands != null)) && (CurrentTargetAttackable(20.0, false, false) && !Me.CurrentTarget.IsPet)) && (Me.CurrentTarget.HealthPercent <= THSettings.Instance.ProfBuffHP)) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Gloves Buff Activated on Enemy Unit Low HP");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 8) && (Me.Inventory.Equipped.Hands != null)) && (Me.ManaPercent <= THSettings.Instance.ProfBuffHP)) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Gloves Buff Activated on Low Mana");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 9) && (Me.Inventory.Equipped.Hands != null)) && BuffBurst(Me)) && CanUseCheck(Me.Inventory.Equipped.Hands), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Gloves Buff Activated on Using Cooldown");
                    StyxWoW.Me.Inventory.Equipped.Hands.Use();
                    LastCastSpell = "SProfBuff";
                    return RunStatus.Failure;
                })), new Decorator(ret => (THSettings.Instance.ProfBuff == 1) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Cooldown");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 2) && CurrentTargetAttackable(30.0, false, false)) && Me.CurrentTarget.IsBoss) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Cooldown (Boss Only");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                })), new Decorator(ret => ((THSettings.Instance.ProfBuff == 3) && THSettings.Instance.Burst) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Burst Mode");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 4) && Me.Combat) && DebuffCCDuration(Me, 3000.0, false)) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Lose Control");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                })), new Decorator(ret => ((THSettings.Instance.ProfBuff == 5) && (Me.HealthPercent <= THSettings.Instance.ProfBuffHP)) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Low HP");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 6) && UnitHealIsValid) && (HealWeightUnitHeal <= THSettings.Instance.ProfBuffHP)) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Friendly Unit Low HP");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.ProfBuff == 7) && CurrentTargetAttackable(20.0, false, false)) && (!Me.CurrentTarget.IsPet && (Me.CurrentTarget.HealthPercent <= THSettings.Instance.ProfBuffHP))) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Enemy Unit Low HP");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                })), 
                new Decorator(ret => ((THSettings.Instance.ProfBuff == 8) && (Me.ManaPercent <= THSettings.Instance.ProfBuffHP)) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Low Mana");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                })), new Decorator(ret => ((THSettings.Instance.ProfBuff == 9) && BuffBurst(Me)) && CanCastCheck("Lifeblood", true), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Use: Lifeblood Activated on Using Cooldown");
                    CastSpell("Lifeblood", Me, "");
                    return RunStatus.Failure;
                }))
             };
            return new Decorator(ret => ((THSettings.Instance.ProfBuff == 1) && Me.Combat) && !Me.Mounted, new PrioritySelector(children));
        }

        private static Composite UseRacial()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.AutoRacial && Me.Combat) && (!MeHasAura("Sap") && !MeHasAura("Scatter Shot"))) && CanCastCheck("Every Man for Himself", true)) && DebuffCCDuration(Me, 3000.0, false), new Styx.TreeSharp.Action(delegate (object param0) {
                if ((THSettings.Instance.AutoTarget && (Me.CurrentTarget == null)) && ((MyLastTarget != null) && MyLastTarget.IsValid))
                {
                    MyLastTarget.Target();
                }
                Styx.Common.Logging.Write("Use: Every Man for Himself");
                CastSpell("Every Man for Himself", Me, "");
                return RunStatus.Failure;
            })), new Decorator(ret => ((THSettings.Instance.AutoRacial && (Me.HealthPercent < THSettings.Instance.UrgentHeal)) && Me.Combat) && CanCastCheck("Stoneform", true), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Stoneform", Me, "");
                return RunStatus.Failure;
            })), new Decorator(ret => ((THSettings.Instance.AutoRacial && (Me.HealthPercent < THSettings.Instance.UrgentHeal)) && Me.Combat) && CanCastCheck("Gift of the Naaru", true), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Gift of the Naaru", Me, "");
                return RunStatus.Failure;
            })) });
        }

        private static Composite UseTrinket()
        {
            return new PrioritySelector(new Composite[] { 
                new Decorator(ret => (((THSettings.Instance.Trinket1 == 1) && Me.Combat) && (Me.Inventory.Equipped.Trinket1 != null)) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Cooldown");
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    LastCastSpell = "STrinket1";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.Trinket1 == 2) && Me.Combat) && (CurrentTargetAttackable(30.0, false, false) && Me.CurrentTarget.IsBoss)) && (Me.Inventory.Equipped.Trinket1 != null)) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Cooldown (Boss Only");
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    LastCastSpell = "STrinket1";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.Trinket1 == 3) && THSettings.Instance.Burst) && (Me.Combat && (Me.Inventory.Equipped.Trinket1 != null))) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Burst Mode");
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    LastCastSpell = "STrinket1";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.Trinket1 == 4) && (LastBreakCC < DateTime.Now)) && (Me.Combat && (Me.Inventory.Equipped.Trinket1 != null))) && ((!MeHasAura("Scatter Shot") && !MeHasAura("Sap")) && DebuffCCDuration(Me, 3000.0, true))) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Lose Control");
                    LastCastSpell = "STrinket1";
                    LastBreakCC = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.Trinket1 == 5) && Me.Combat) && ((Me.Inventory.Equipped.Trinket1 != null) && (Me.HealthPercent < THSettings.Instance.Trinket1HP))) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Low HP");
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    LastCastSpell = "STrinket1";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.Trinket1 == 6) && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.Trinket1HP) && Me.Combat)) && (Me.Inventory.Equipped.Trinket1 != null)) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Friendly Unit Low HP");
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    LastCastSpell = "STrinket1";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.Trinket1 == 7) && Me.Combat) && ((Me.Inventory.Equipped.Trinket1 != null) && CurrentTargetAttackable(20.0, false, false))) && (!Me.CurrentTarget.IsPet && (Me.CurrentTarget.HealthPercent <= THSettings.Instance.Trinket1HP))) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Enemy Unit Low HP");
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    LastCastSpell = "STrinket1";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.Trinket1 == 8) && Me.Combat) && ((Me.Inventory.Equipped.Trinket1 != null) && (Me.ManaPercent <= THSettings.Instance.Trinket1HP))) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Low Mana");
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    LastCastSpell = "STrinket1";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.Trinket1 == 9) && Me.Combat) && ((Me.Inventory.Equipped.Trinket1 != null) && BuffBurst(Me))) && CanUseCheck(Me.Inventory.Equipped.Trinket1), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Using Cooldown");
                    StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                    LastCastSpell = "STrinket1";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.Trinket2 == 1) && Me.Combat) && (Me.Inventory.Equipped.Trinket2 != null)) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Cooldown");
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    LastCastSpell = "STrinket2";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.Trinket2 == 2) && Me.Combat) && (CurrentTargetAttackable(30.0, false, false) && Me.CurrentTarget.IsBoss)) && (Me.Inventory.Equipped.Trinket2 != null)) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Cooldown (Boss Only");
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    LastCastSpell = "STrinket2";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.Trinket2 == 3) && THSettings.Instance.Burst) && (Me.Combat && (Me.Inventory.Equipped.Trinket2 != null))) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Burst Mode");
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    LastCastSpell = "STrinket2";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.Trinket2 == 4) && (LastBreakCC < DateTime.Now)) && (Me.Combat && (Me.Inventory.Equipped.Trinket2 != null))) && ((!MeHasAura("Scatter Shot") && !MeHasAura("Sap")) && DebuffCCDuration(Me, 3000.0, true))) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Lose Control");
                    LastCastSpell = "STrinket2";
                    LastBreakCC = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.Trinket2 == 5) && Me.Combat) && ((Me.Inventory.Equipped.Trinket2 != null) && (Me.HealthPercent <= THSettings.Instance.Trinket2HP))) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Low HP");
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    LastCastSpell = "STrinket2";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.Trinket2 == 6) && UnitHealIsValid) && ((HealWeightUnitHeal <= THSettings.Instance.Trinket2HP) && Me.Combat)) && (Me.Inventory.Equipped.Trinket2 != null)) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Friendly Unit Low HP");
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    LastCastSpell = "STrinket2";
                    return RunStatus.Failure;
                })), new Decorator(ret => ((((THSettings.Instance.Trinket2 == 7) && Me.Combat) && ((Me.Inventory.Equipped.Trinket2 != null) && CurrentTargetAttackable(20.0, false, false))) && (!Me.CurrentTarget.IsPet && (Me.CurrentTarget.HealthPercent <= THSettings.Instance.Trinket2HP))) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Enemy Unit Low HP");
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    LastCastSpell = "STrinket2";
                    return RunStatus.Failure;
                })), 
                new Decorator(ret => (((THSettings.Instance.Trinket2 == 8) && Me.Combat) && ((Me.Inventory.Equipped.Trinket2 != null) && (Me.ManaPercent <= THSettings.Instance.Trinket2HP))) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Low Mana");
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    LastCastSpell = "STrinket2";
                    return RunStatus.Failure;
                })), new Decorator(ret => (((THSettings.Instance.Trinket2 == 9) && Me.Combat) && ((Me.Inventory.Equipped.Trinket2 != null) && BuffBurst(Me))) && CanUseCheck(Me.Inventory.Equipped.Trinket2), new Styx.TreeSharp.Action(delegate (object param0) {
                    Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Using Cooldown");
                    StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                    LastCastSpell = "STrinket2";
                    return RunStatus.Failure;
                }))
             });
        }

        private static void UseTrinketVoid()
        {
            if (Me.Combat && !Me.Mounted)
            {
                switch (THSettings.Instance.Trinket1)
                {
                    case 1:
                        if ((Me.Inventory.Equipped.Trinket1 != null) && CanUseCheck(Me.Inventory.Equipped.Trinket1))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Cooldown");
                        }
                        break;

                    case 2:
                        if ((CurrentTargetAttackable(30.0, false, false) && Me.CurrentTarget.IsBoss) && ((Me.Inventory.Equipped.Trinket1 != null) && CanUseCheck(Me.Inventory.Equipped.Trinket1)))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Cooldown (Boss Only");
                        }
                        break;

                    case 3:
                        if ((THSettings.Instance.Burst && (Me.Inventory.Equipped.Trinket1 != null)) && CanUseCheck(Me.Inventory.Equipped.Trinket1))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Burst Mode");
                        }
                        break;

                    case 4:
                        if ((((LastBreakCC < DateTime.Now) && (Me.Inventory.Equipped.Trinket1 != null)) && (!MeHasAura("Scatter Shot") && !MeHasAura("Sap"))) && (DebuffCCDuration(Me, 3000.0, true) && CanUseCheck(Me.Inventory.Equipped.Trinket1)))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Lose Control");
                        }
                        break;

                    case 5:
                        if (((Me.Inventory.Equipped.Trinket1 != null) && (Me.HealthPercent < THSettings.Instance.Trinket1HP)) && CanUseCheck(Me.Inventory.Equipped.Trinket1))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Low HP");
                        }
                        break;

                    case 6:
                        if (((UnitHealIsValid && (HealWeightUnitHeal <= THSettings.Instance.Trinket1HP)) && (Me.Combat && (Me.Inventory.Equipped.Trinket1 != null))) && CanUseCheck(Me.Inventory.Equipped.Trinket1))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Friendly Unit Low HP");
                        }
                        break;

                    case 7:
                        if ((((Me.Inventory.Equipped.Trinket1 != null) && CurrentTargetAttackable(20.0, false, false)) && (!Me.CurrentTarget.IsPet && (Me.CurrentTarget.HealthPercent <= THSettings.Instance.Trinket1HP))) && CanUseCheck(Me.Inventory.Equipped.Trinket1))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Enemy Unit Low HP");
                        }
                        break;

                    case 8:
                        if (((Me.Inventory.Equipped.Trinket1 != null) && (Me.ManaPercent <= THSettings.Instance.Trinket1HP)) && CanUseCheck(Me.Inventory.Equipped.Trinket1))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Low Mana");
                        }
                        break;

                    case 9:
                        if ((Me.Combat && (Me.Inventory.Equipped.Trinket1 != null)) && (BuffBurst(Me) && CanUseCheck(Me.Inventory.Equipped.Trinket1)))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name + " on Using Cooldown");
                        }
                        break;
                }
                switch (THSettings.Instance.Trinket2)
                {
                    case 1:
                        if ((Me.Inventory.Equipped.Trinket2 == null) || !CanUseCheck(Me.Inventory.Equipped.Trinket2))
                        {
                            break;
                        }
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Cooldown");
                        return;

                    case 2:
                        if ((!CurrentTargetAttackable(30.0, false, false) || !Me.CurrentTarget.IsBoss) || ((Me.Inventory.Equipped.Trinket2 == null) || !CanUseCheck(Me.Inventory.Equipped.Trinket2)))
                        {
                            break;
                        }
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Cooldown (Boss Only");
                        return;

                    case 3:
                        if ((!THSettings.Instance.Burst || (Me.Inventory.Equipped.Trinket2 == null)) || !CanUseCheck(Me.Inventory.Equipped.Trinket2))
                        {
                            break;
                        }
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Burst Mode");
                        return;

                    case 4:
                        if ((((LastBreakCC >= DateTime.Now) || (Me.Inventory.Equipped.Trinket2 == null)) || (MeHasAura("Scatter Shot") || MeHasAura("Sap"))) || (!DebuffCCDuration(Me, 3000.0, true) || !CanUseCheck(Me.Inventory.Equipped.Trinket2)))
                        {
                            break;
                        }
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Lose Control");
                        return;

                    case 5:
                        if ((!Me.Combat || (Me.Inventory.Equipped.Trinket2 == null)) || ((Me.HealthPercent >= THSettings.Instance.Trinket2HP) || !CanUseCheck(Me.Inventory.Equipped.Trinket2)))
                        {
                            break;
                        }
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Low HP");
                        return;

                    case 6:
                        if ((!UnitHealIsValid || (HealWeightUnitHeal > THSettings.Instance.Trinket2HP)) || ((Me.Inventory.Equipped.Trinket2 == null) || !CanUseCheck(Me.Inventory.Equipped.Trinket2)))
                        {
                            break;
                        }
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Friendly Unit Low HP");
                        return;

                    case 7:
                        if ((((Me.Inventory.Equipped.Trinket2 == null) || !CurrentTargetAttackable(20.0, false, false)) || (Me.CurrentTarget.IsPet || (Me.CurrentTarget.HealthPercent > THSettings.Instance.Trinket2HP))) || !CanUseCheck(Me.Inventory.Equipped.Trinket2))
                        {
                            break;
                        }
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Enemy Unit Low HP");
                        return;

                    case 8:
                        if (((Me.Inventory.Equipped.Trinket2 == null) || (Me.ManaPercent > THSettings.Instance.Trinket2HP)) || !CanUseCheck(Me.Inventory.Equipped.Trinket2))
                        {
                            break;
                        }
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Low Mana");
                        return;

                    case 9:
                        if (((Me.Inventory.Equipped.Trinket2 != null) && BuffBurst(Me)) && CanUseCheck(Me.Inventory.Equipped.Trinket2))
                        {
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            Styx.Common.Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name + " on Using Cooldown");
                        }
                        break;

                    default:
                        return;
                }
            }
        }

        private void WarStompVoid()
        {
            if (((THSettings.Instance.AutoRacial && (HealWeightUnitHeal > THSettings.Instance.PriorityHeal)) && ((LastInterrupt < DateTime.Now) && (UnitHeal != null))) && ((UnitHeal.IsValid && !IsMoving(Me)) && (CanCastCheck("War Stomp", false) && GetUnitWarStomp())))
            {
                if (Me.IsCasting)
                {
                    SpellManager.StopCasting();
                }
                if (UnitWarStomp.IsCasting)
                {
                    CastSpell("War Stomp", Me, "War Stomp");
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
                }
            }
        }

        private static Composite WaterShield()
        {
            return new Decorator(delegate (object ret) {
                if (!THSettings.Instance.WaterShield || (((MyAura("Water Shield", Me) || MyAura("Earth Shield", Me)) || MyAura("Lightning Shield", Me)) && (((!Me.CurrentMap.IsDungeon && !Me.CurrentMap.IsRaid) && !(Me.CurrentMap.Name == "Proving Grounds")) || MyAura("Water Shield", Me))))
                {
                    return false;
                }
                return CanCastCheck("Water Shield", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Water Shield", Me, "WaterShield");
            }));
        }

        private static Composite WaterShieldAlways()
        {
            return new Decorator(delegate (object ret) {
                if (((!THSettings.Instance.WaterShieldAlways || (Me.ManaPercent > THSettings.Instance.WaterShieldAlwaysMana)) || MyAura("Water Shield", Me)) || (((Me.ManaPercent > 10.0) && MyAura("Earth Shield", Me)) && (!MyAura("Earth Shield", Me) || (Me.HealthPercent < THSettings.Instance.EarthShieldAlwaysHP))))
                {
                    return false;
                }
                return CanCastCheck("Water Shield", false);
            }, new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Water Shield", Me, "WaterShieldAlways");
            }));
        }

        private static Composite WaterWalking()
        {
            return new Decorator(ret => (((THSettings.Instance.AutoWaterWalking && (HealWeightUnitHeal >= THSettings.Instance.DoNotHealAbove)) && ((WaterWalkingLast < DateTime.Now) && !Me.Combat)) && (((Me.ManaPercent >= THSettings.Instance.UrgentHeal) && !MeHasAura("Water Walking")) && CanCastCheck("Water Walking", false))) && !DebuffDot(Me), new Styx.TreeSharp.Action(delegate (object param0) {
                WaterWalkingLast = DateTime.Now + TimeSpan.FromMilliseconds(5000.0);
                CastSpell("Water Walking", Me, "WaterWalking");
            }));
        }

        private static void WindShearInterruptVoid()
        {
            if ((THSettings.Instance.WindShearInterrupt && (((UseSpecialization != 3) || ((UseSpecialization == 3) && !UnitHealIsValid)) || (((UseSpecialization == 3) && UnitHealIsValid) && (HealWeightUnitHeal > THSettings.Instance.UrgentHeal)))) && (((LastInterrupt < DateTime.Now) && CanCastCheck("Wind Shear", true)) && GetUnitWindShear()))
            {
                if (Me.IsCasting)
                {
                    SpellManager.StopCasting();
                }
                SafelyFacingTarget(UnitWindShear);
                if ((UnitWindShear.IsCasting && (UnitWindShear.CurrentCastTimeLeft.TotalMilliseconds > (MyLatency + 50.0))) || UnitWindShear.IsChanneling)
                {
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500.0);
                    CastSpell("Wind Shear", UnitWindShear, string.Concat(new object[] { "Casting ", UnitWindShear.CastingSpell.Name, " - ", UnitWindShear.CastingSpellId }));
                }
            }
        }

        private static Composite Windwalk()
        {
            return new PrioritySelector(new Composite[] { new Decorator(ret => (((THSettings.Instance.WindwalkRootMe && (HealWeightUnitHeal >= THSettings.Instance.UrgentHeal)) && ((UseSpecialization == 3) && Me.Combat)) && ((!MyTotemCheck("Earth Elemental Totem", Me, 40) && CanCastCheck("Windwalk Totem", true)) && DebuffRoot(Me))) && HaveDPSTarget(Me), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Windwalk Totem", Me, "WindwalkRootMeResto");
                return RunStatus.Failure;
            })), new Decorator(ret => (((THSettings.Instance.WindwalkRootMe && (UseSpecialization != 3)) && (Me.Combat && !MyTotemCheck("Earth Elemental Totem", Me, 40))) && (CurrentTargetAttackable(40.0, false, false) && CanCastCheck("Windwalk Totem", true))) && DebuffRoot(Me), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Windwalk Totem", Me, "WindwalkRootMeEleEnh");
                return RunStatus.Failure;
            })), new Decorator(ret => (((THSettings.Instance.WindwalkRootFriend && (HealWeightUnitHeal >= THSettings.Instance.UrgentHeal)) && ((UseSpecialization == 3) && !MyTotemCheck("Earth Elemental Totem", Me, 40))) && CanCastCheck("Windwalk Totem", true)) && NeedFriendWindwalk(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Windwalk Totem", Me, "WindwalkRootFriendResto");
                return RunStatus.Failure;
            })), new Decorator(ret => ((THSettings.Instance.WindwalkRootFriend && (UseSpecialization != 3)) && (!MyTotemCheck("Earth Elemental Totem", Me, 40) && CanCastCheck("Windwalk Totem", true))) && NeedFriendWindwalk(), new Styx.TreeSharp.Action(delegate (object param0) {
                CastSpell("Windwalk Totem", Me, "WindwalkRootFriendEleEnh");
                return RunStatus.Failure;
            })) });
        }

        private static Composite WriteDebug(string message)
        {
            return new Styx.TreeSharp.Action(delegate (object param0) {
                if (message != "")
                {
                    object[] objArray = new object[4];
                    objArray[0] = "(";
                    TimeSpan span = (TimeSpan) (DateTime.Now - LastWriteDebug);
                    objArray[1] = Math.Round(span.TotalMilliseconds, 0);
                    objArray[2] = ") ";
                    objArray[3] = message;
                    Styx.Common.Logging.Write(string.Concat(objArray));
                    LastWriteDebug = DateTime.Now;
                }
                return RunStatus.Failure;
            });
        }

        public override WoWClass Class
        {
            get
            {
                return WoWClass.Shaman;
            }
        }

        public override Composite CombatBehavior
        {
            get
            {
                return this._combatBehavior;
            }
        }

        public override Composite DeathBehavior
        {
            get
            {
                return this._deathBehavior;
            }
        }

        private static IEnumerable<WoWPartyMember> GroupMembers
        {
            get
            {
                if (Me.GroupInfo.IsInRaid)
                {
                    return Me.GroupInfo.RaidMembers;
                }
                return Me.GroupInfo.PartyMembers;
            }
        }

        private static LocalPlayer Me
        {
            get
            {
                return StyxWoW.Me;
            }
        }

        private static double MobsNearby
        {
            [CompilerGenerated]
            get
            {
                return <MobsNearby>k__BackingField;
            }
            [CompilerGenerated]
            set
            {
                <MobsNearby>k__BackingField = value;
            }
        }

        public override string Name
        {
            get
            {
                return "TuanHA Shaman [Special Edition]";
            }
        }

        public override Composite PreCombatBuffBehavior
        {
            get
            {
                return this._preCombatBuffBehavior;
            }
        }

        public override Composite RestBehavior
        {
            get
            {
                return this._restBehavior;
            }
        }

        private static string SelfRezSpell
        {
            [CompilerGenerated]
            get
            {
                return <SelfRezSpell>k__BackingField;
            }
            [CompilerGenerated]
            set
            {
                <SelfRezSpell>k__BackingField = value;
            }
        }

        public override bool WantButton
        {
            get
            {
                return true;
            }
        }

        public class CallTrace : PrioritySelector
        {
            private static bool _init;

            public CallTrace(string name, params Composite[] children) : base(children)
            {
                Initialize();
                this.Name = name;
                LastCall = DateTime.MinValue;
            }

            private static void Initialize()
            {
                if (!_init)
                {
                    _init = true;
                }
            }

            public override RunStatus Tick(object context)
            {
                CountCall += (ulong) 1L;
                if (!TraceActive)
                {
                    return base.Tick(context);
                }
                DateTime now = DateTime.Now;
                RunStatus status = base.Tick(context);
                object[] args = new object[2];
                args[0] = this.Name;
                TimeSpan span = (TimeSpan) (DateTime.Now - now);
                args[1] = (ulong) span.TotalMilliseconds;
                Styx.Common.Logging.Write("... leave: {0}, took {1} ms", args);
                return status;
            }

            private static ulong CountCall
            {
                [CompilerGenerated]
                get
                {
                    return <CountCall>k__BackingField;
                }
                [CompilerGenerated]
                set
                {
                    <CountCall>k__BackingField = value;
                }
            }

            private static DateTime LastCall
            {
                [CompilerGenerated]
                get
                {
                    return <LastCall>k__BackingField;
                }
                [CompilerGenerated]
                set
                {
                    <LastCall>k__BackingField = value;
                }
            }

            private string Name { get; set; }

            private static bool TraceActive
            {
                get
                {
                    return true;
                }
            }
        }

        public delegate float DynamicRangeRetriever(object context);

        public delegate WoWPoint LocationRetriever(object context);

        public delegate WoWPoint LocationRetriverDelegate(object context);

        [UsedImplicitly]
        private class LockSelector : PrioritySelector
        {
            public LockSelector(params Composite[] children) : base(children)
            {
            }

            public override RunStatus Tick(object context)
            {
                using (StyxWoW.Memory.AcquireFrame())
                {
                    return base.Tick(context);
                }
            }
        }

        public delegate bool SimpleBooleanDelegate(object context);

        public delegate WoWUnit UnitSelectionDelegate(object context);
    }
}

